4 个版本 (2 个破坏性更新)

0.3.1 2024年2月28日
0.3.0 2024年2月16日
0.2.0 2020年12月4日
0.1.0 2020年8月13日

#251 in 异步

MIT 许可证

47KB
792

Hass-Rs

一个简单的用于与 Home Assistant WebSocket API 交互的异步 Rust 客户端库。

测试环境

连接到您的 Home Assistant 服务器,或遵循 安装指南 中的说明。
为了开发,可以使用 docker 来轻松搭建测试环境。

运行提供的示例的步骤

  • 克隆 hass_rs github 仓库
  • 在 docker 容器中运行 homeassistant 服务器
docker run -d --name="home-assistant" -v /PATH_TO_YOUR_CONFIG:/config -v /etc/localtime:/etc/localtime:ro --net=host homeassistant/home-assistant:stable
  • 登录到 Home Assistant 网页界面:https://127.0.0.1:8123/
  • 转到 配置文件 --> 长期活动访问令牌 并创建一个用于 hass_rs 客户端的令牌
  • 设置环境变量 export HASS_TOKEN=<YOUR_TOKEN_HERE>
  • 运行示例脚本
    • cargorun --exampleget_cmds
    • cargorun --examplecall_service
    • cargorun --examplesubscribe_event
    • cargo run --example get_cmds_async_std --features use-async-std --no-default-features - 使用 async-std 运行时的示例

示例用法

查看 示例文件夹 以获取有关如何使用各种 hass-rs 函数的更多详细信息。

use hass_rs::client::HassClient;

use async_tungstenite::tungstenite::{Error, Message};
use futures_util::{
    stream::{SplitSink, SplitStream},
    SinkExt, StreamExt,
};
use lazy_static::lazy_static;
use std::env::var;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::sync::{mpsc, mpsc::Receiver, mpsc::Sender};
use tokio_tungstenite::{connect_async, WebSocketStream};

lazy_static! {
    static ref TOKEN: String =
        var("HASS_TOKEN").expect("please set up the HASS_TOKEN env variable before running this");
}

async fn ws_incoming_messages(
    mut stream: SplitStream<WebSocketStream<impl AsyncRead + AsyncWrite + Unpin>>,
    to_user: Sender<Result<Message, Error>>,
) {
    loop {
        while let Some(message) = stream.next().await {
            let _ = to_user.send(message).await;
        }
    }
}

async fn ws_outgoing_messages(
    mut sink: SplitSink<WebSocketStream<impl AsyncRead + AsyncWrite + Unpin>, Message>,
    mut from_user: Receiver<Message>,
) {
    loop {
        match from_user.recv().await {
            Some(msg) => sink.send(msg).await.expect("Failed to send message"),
            None => continue,
        }
    }
}

#[tokio::main]
async fn main() {
    let url = "ws://127.0.0.1:8123/api/websocket";

    println!("Connecting to - {}", url);
    let (wsclient, _) = connect_async(url).await.expect("Failed to connect");
    let (sink, stream) = wsclient.split();

    //Channels to recieve the Client Command and send it over to Websocket server
    let (to_gateway, from_user) = mpsc::channel::<Message>(20);
    //Channels to receive the Response from the Websocket server and send it over to Client
    let (to_user, from_gateway) = mpsc::channel::<Result<Message, Error>>(20);

    // Handle incoming messages in a separate task
    let read_handle = tokio::spawn(ws_incoming_messages(stream, to_user));

    // Read from command line and send messages
    let write_handle = tokio::spawn(ws_outgoing_messages(sink, from_user));

    let mut client = HassClient::new(to_gateway, from_gateway);

    client
        .auth_with_longlivedtoken(&*TOKEN)
        .await
        .expect("Not able to autheticate");

    println!("WebSocket connection and authethication works\n");

    println!("Getting the Config:\n");
    let cmd2 = client
        .get_config()
        .await
        .expect("Unable to retrieve the Config");
    println!("config: {}\n", cmd2);

    // Await both tasks (optional, depending on your use case)
    let _ = tokio::try_join!(read_handle, write_handle);
}

开发状态

  • 创建客户端
    • 自动重连(待定)
    • 使用长期活动访问令牌进行认证
    • 使用 OAuth2 进行认证(待定)
  • 调用服务
  • 订阅
    • 事件
    • 配置(需要吗?提出问题)
    • 服务(需要吗?提出问题)
  • 取消订阅
  • 获取命令
    • 获取状态
    • 获取配置
    • 获取服务
    • 获取面板
    • 获取媒体播放器缩略图(您需要这个吗?请提交一个问题)
  • ping - pong

依赖项

~2–16MB
~176K SLoC