#devices #alexa #control #talk #turn #off #rustmo

rustmo-server

通过Alexa与Rustmo的代码对话

3个版本

0.1.2 2020年5月15日
0.1.1 2019年12月9日
0.1.0 2019年12月8日

#562 in HTTP服务器


用于rustmo-devices

MIT许可

36KB
707

Rustmo - 用Rust与您的代码对话!

Rustmo是一个库,允许创建可以通过Alexa启用的事物(如Amazon Echo Dot)控制的虚拟设备。

Rustmo基于Fauxmo,类似于Fauxmo,本质上模拟了Belkin WeMo设备,并由Rust代码支持。

Rustmo简单模拟电源"插座"。因此,虚拟设备只有两种状态: OnOff

在幕后,Rustmo为每个 VirtualDevice 创建一个 SSDP 监听器以及一个网络服务器。Rustmo负责细节,您只需实现 VirtualDevice 特性以响应Alexa请求。

依赖项

声明对 rustmo-server 的依赖

[dependencies]
rustmo-server = "0.1.0"

实现 VirtualDevice 特性

其次,创建一个表示您的设备的结构体。您的"设备"可以是100%纯代码,或者它可能是围绕一个专有网络协议的包装,该协议控制您网络上的某个物理(但非Alexa兼容)设备。

有关这些示例,请参阅rustmo-devices crate,其中包含几个 VirtualDevice 实现尝试控制Sony接收器、Sony投影仪和Oppo DVD播放器。

以下是一个简单的仅代码示例

use rustmo_server::virtual_device::{VirtualDevice, VirtualDeviceError, VirtualDeviceState};

struct MyDevice {
    state: VirtualDeviceState,
}

impl MyDevice {
    fn new() -> Self {
        MyDevice{
            state: VirtualDeviceState::Off
        }
    }
}

impl VirtualDevice for MyDevice {
    fn turn_on(&mut self) -> Result<VirtualDeviceState, VirtualDeviceError> {
        eprintln!("Turning on");
        self.state = VirtualDeviceState::On;
        Ok(self.state)
    }

    fn turn_off(&mut self) -> Result<VirtualDeviceState, VirtualDeviceError> {
        eprintln!("Turning off");
        self.state = VirtualDeviceState::Off;
        Ok(self.state)
    }

    fn check_is_on(&mut self) -> Result<VirtualDeviceState, VirtualDeviceError> {
        eprintln!("Checking state");
        Ok(self.state)
    }
}

创建RustmoServer,添加设备

接下来,您需要创建一个 RustmoServer 实例。它需要监听Alexa设备也连接的任何网络接口。

一旦创建,您可以添加一个或多个 VirtualDevice 实现实例,这使得它们立即可由Alexa发现。一旦发现,就可以立即控制。

use std::net::Ipv4Addr;
use std::str::FromStr;
use std::thread;

use rustmo_server::RustmoServer;

use crate::example::*;

fn main() -> std::io::Result<()> {
    // create the rustmo server and start listening for SSDP discovery requests 
    let mut server = RustmoServer::new(Ipv4Addr::from_str("192.168.0.100").unwrap());

    // add "My Device", making it controllable via Alexa on the specified port (1100)
    let _my_device = server.add_device("My Device", 1100, MyDevice::new())?;

    // wait forever
    thread::park();
    Ok(())
}

存在各种其他辅助方法,用于添加在状态更改时需要轮询其状态的设备,在状态更改时需要撒谎其状态的设备,将设备组合成组等。

添加一个VirtualDevice将返回一个WrappedVirtualDevice,它是在一个Arc<Mutex<Box<dyn VirtualDevice>>>中包装的你的设备实例。这是RustmoServer内部用于响应Alexa请求相同的类型实例。你可以在其他VirtualDevice实现中使用它,这些实现可能涉及跨多个设备的更复杂操作,并且当控制底层设备时可以保证线程安全。

注意,每个设备都需要一个唯一的端口号来监听Alexa请求。

通过Alexa与你的VirtualDevice对话

既然你已经启动了Rustmo服务器并添加了一个设备,你首先需要让Alexa发现新的设备。

只需说:Alexa, discover devices

大约45秒后,Alexa应该已经找到了名为"My Device"的设备。

现在你可以通过以下命令让Alexa打开或关闭它:

  • Alexa,打开My Device
  • Alexa,关闭my device

注意,Alexa知道如何发送到Rustmo设备(再次提醒,这些是仿制的Belkin WeMo电源插座)的命令只有'On'和'Off'。无法让Alexa执行特定操作,如"换频道"或"告诉我天气"。这些事情需要通过Alexa技能来实现,这超出了本项目的范围。

关于一些VirtualDevice实现的注意事项

当你要求Alexa打开或关闭设备时,它期望在5秒内收到响应。如果在那个时间内Alexa没有收到响应,它将认为设备"没有响应"。

当设备的状态改变时,Alexa会立即通过VirtualDevicecheck_is_on()方法查询设备的状态。如果对该查询的响应与Alexa期望的不匹配,Alexa将报告设备"故障"。

动机

这个项目的动机是让我丢失家中电影院所有的遥控器。

能够通过一个语音命令打开或关闭所有设备,并通过自定义移动应用程序控制其他设备特定的功能,对我的高端生活来说是一个巨大的生活质量提升。

许可

此代码根据MIT许可证授权。版权所有2019,ZomboDB,LLC。

依赖关系

~24MB
~517K SLoC