#设备 #pixoo #动画 #控制 #控制 #频道 #API绑定

divoom

Rust API 用于控制 divoom 设备,如 pixoo

13 个版本

0.1.42 2022年8月7日
0.1.39 2022年8月6日
0.1.23 2022年7月30日

#442 in 硬件支持

每月 25 次下载
用于 2 个 Crates

Apache-2.0

240KB
5.5K SLoC

Divoom

Divoom

用于控制支持 REST API 的 divoom 设备(如 pixoo-64)的 Rust 库,根据 divoom 的 api/doc 组织,未来可能还有更多。

Crates.io GitHub release (latest SemVer) Documentation License: Apache 2.0 Build Status

// Get current channel
use divoom::*;

println!(
    "{}",
    PixooClient::new("192.168.0.123").get_current_channel().await?
);

// Output: clock

除了 SDK,还提供了一些其他工具,帮助人们享受设备,同时也作为演示!

  • 命令行工具 divoom-cli 用于控制设备:[https://github.com/r12f/divoom/tree/main/divoom_cli](https://github.com/r12f/divoom/tree/main/divoom_cli)。

    # Check current channel
    > divoom-cli 192.168.0.123 channel get
    ---
    clock
    
  • 带有 Swagger UI 和 OpenAPI 规范 json 的 REST 网关 divoom-gateway,因此我们可以控制设备,构建类似 cron 的计划,渲染自定义动画并在设备上播放:[https://github.com/r12f/divoom/tree/main/divoom_gateway](https://github.com/r12f/divoom/tree/main/divoom_gateway)。

如何使用

要使用此库,请在 Cargo.toml 文件中的依赖项中添加以下内容

[dependencies]
divoom = "0.1"

该库包含两个主要部分

  • Divoom 服务 API,用于与 Divoom 的后端服务进行通信,用于设备发现等。
  • Pixoo 设备 API,用于通过其 REST API 与特定设备通信。

Divoom 服务 API

要发现您局域网中的所有设备,我们可以使用 get_same_lan_devices API 从 Divoom 的后端服务获取所有设备。

use divoom::*;

let divoom = DivoomServiceClient::new();
let devices = divoom.get_same_lan_devices().await?;
devices.iter().for_each(|x| println!("{:?}", x));

这将输出

DivoomDeviceInfo { device_name: "Pixoo", device_id: 300000001, device_private_ip: "192.168.0.123" }

Pixoo 设备 API

一旦我们获取了设备地址,我们就可以使用它来创建一个 pixoo 客户端并与之通信

use divoom::*;

let pixoo = PixooClient::new("192.168.0.123");
let result = pixoo.get_current_channel().await?;
println!("{:?}", result);

这将输出

Clock

目前,我们支持以下 API

  • 频道 API
    • 选择频道
    • 获取当前频道
    • 选择时钟
    • 获取所选时钟信息
    • 选择云频道
    • 选择可视化器
    • 选择自定义页面
  • 系统/设备 API
    • 获取设备设置
    • 获取设备时间
    • 设置设备亮度
    • 设置设备时间
    • 设置设备高亮模式
    • 设置设备小时模式
    • 设置设备镜像模式
    • 设置设备旋转角度
    • 设置设备屏幕电源状态
    • 设置设备温度单位
    • 设置设备时区
    • 设置设备天气区域
    • 设置设备白平衡
  • 工具 API
    • 设置倒计时工具
    • 设置噪音工具
    • 设置计分板工具
    • 设置秒表工具
  • 动画 API
    • 从文件播放 gif
    • 获取下一个动画 ID
    • 重置下一个动画 ID
    • 发送图片动画
    • 发送文本动画
    • 清除所有文本区域
    • 播放蜂鸣器
  • 批处理API
    • 批处理命令
    • 从URL执行命令

图像动画

如Pixoo-64等设备支持从文件或直接从互联网播放GIF文件,我们只需指定以下URL即可

use divoom::*;

let pixoo = PixooClient::new("192.168.0.123");
pixoo.play_gif_file(DivoomFileAnimationSourceType::Url, "<Some URL goes here>").await?;

然而,该设备API(截至2022年7月)尚不稳定,最可靠的播放GIF的方法是创建一个动画,并逐个绘制所有GIF帧。为了帮助这个过程,我们创建了一个资源加载器和动画构建器。

use divoom::*;

// Load the resource.
let frames = DivoomAnimationResourceLoader::gif_file("test_data/animation_builder_tests/logo-16-rotate-4-frames.gif").unwrap();

// Build animation with 16 pixel canvas and 100ms frame play speed.
let builder = DivoomAnimationBuilder::new(16, Duration::from_millis(100)).unwrap();
let animation = builder.draw_frames(&frames, 0).build();

// Send to device here.
let pixoo = PixooClient::new("192.168.0.123");
pixoo.send_image_animation(animation).await

甚至更简单

use divoom::*;
let pixoo = PixooClient::new("192.168.0.123");
pixoo.render_gif_as_animation(16, Duration::from_millis(100), "test_data/animation_builder_tests/logo-16-rotate-4-frames.gif").await

除了GIF,我们还支持PNG和JPEG格式。除了从文件读取,我们还支持从任何Read特性加载资源。有关如何使用它的更多信息,请查看我们的文档:[https://docs.rs/divoom/latest/divoom/struct.DivoomAnimationBuilder.html](https://docs.rs/divoom/latest/divoom/struct.DivoomAnimationBuilder.html)。

如果出于任何原因,您不想使用内置的动画构建器,我们可以通过指定特性来排除它

[dependencies]
divoom = { version = "0.1", features = [] }

文本动画

要创建文本动画,我们可以使用DivoomTextAnimation结构和send_text_animationAPI来帮助我们

use divoom::*;

let pixoo = PixooClient::new("192.168.0.123");
let animation = DivoomTextAnimation::default(); 
animation.text_string = "Foo".to_string();
pixoo.send_text_animation(animation).await?;

命令批处理

在某些情况下,我们可能想要同时运行很多命令,例如初始化设置。Pixoo设备支持将所有命令批处理为一个请求,但只返回一个结果来指示是否一切成功。

以下是一个示例,我们将多个命令批处理执行以更新设备设置

use divoom::*;
let pixoo = PixooClient::new("192.168.0.123");
pixoo.start_batch()
  .set_device_rotation_angle(DivoomDeviceRotationAngle::Rotate90)
  .set_device_mirror_mode(DivoomDeviceMirrorMode::On)
  .set_device_brightness(30)
  .execute().await.expect("Request should succeed.");

发送原始请求

在发布新API且我们尚未支持它,或我们需要通过发送原始有效负载进行某些实验的情况下,我们可以使用以下API直接发送原始请求,这对单个请求和批处理模式都适用。

单次请求模式

use divoom::*;

let pixoo = PixooClient::new("192.168.0.123");
pixoo.send_raw_request("{ \"Command\": \"Device/SetHighLightMode\", \"Mode\": 0 }").await?.expect("Request should succeed.");

批处理模式

use divoom::*;
let pixoo = PixooClient::new("192.168.0.123");
pixoo.start_batch()
  .send_raw_request("{ \"Command\": \"Device/SetHighLightMode\", \"Mode\": 0 }".into())
  .execute_with_raw_response().await.expect("Request should succeed.");

调试

调试日志以调试级别记录。一旦我们将日志级别设置为调试,我们就能开始看到它

env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();

或者我们可以使用RUST_LOG环境变量来更改级别并启用日志

使用命令工具(下面将介绍),在Windows上

> $env:RUST_LOG="debug"; .\divoom-cli.exe 192.168.0.123 channel get

和在Linux上

RUST_LOG=debug ./divoom-cli.exe 192.168.0.123 channel get

然后我们将看到以下输出日志

[2022-07-10T00:33:50Z DEBUG divoom::clients::common::divoom_rest_client] Sending request: Url = "http://192.168.0.123/post", Body = "{"Command":"Channel/GetIndex"}"
[2022-07-10T00:33:50Z DEBUG reqwest::connect] starting new connection: http://192.168.0.123/
[2022-07-10T00:33:50Z DEBUG hyper::client::connect::http] connecting to 192.168.0.123:80
[2022-07-10T00:33:50Z DEBUG hyper::client::connect::http] connected to 192.168.0.123:80
[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::io] flushed 107 bytes
[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::io] parsed 2 headers
[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::conn] incoming body is chunked encoding
[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::decode] incoming chunked header: 0x22 (34 bytes)
[2022-07-10T00:33:50Z DEBUG reqwest::async_impl::client] response '200 OK' for http://192.168.0.123/post
[2022-07-10T00:33:50Z DEBUG divoom::clients::common::divoom_rest_client] Response header received: StatusCode = 200
[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::conn] incoming body completed
[2022-07-10T00:33:50Z DEBUG hyper::client::pool] pooling idle connection for ("http", 192.168.0.123)
[2022-07-10T00:33:50Z DEBUG divoom::clients::common::divoom_rest_client] Response received: Body = "{"error_code": 0, "SelectIndex":3}"
---
customPage

要将其还原

> $env:RUST_LOG="warn"; .\divoom-cli.exe 192.168.0.123 channel get
---
customPage

致谢

  • 感谢@farique1允许我将经典8位字体打包,这些字体是通过他的项目Chartotype生成的,作为Divoom Gateway的一部分,这有助于生成文本动画。

许可证

Apache-2.0: [https://apache.ac.cn/licenses/LICENSE-2.0](https://apache.ac.cn/licenses/LICENSE-2.0)

依赖项

~17–35MB
~598K SLoC