{"id":18461681,"url":"https://github.com/r12f/divoom","last_synced_at":"2025-08-21T18:33:27.714Z","repository":{"id":44375437,"uuid":"512199392","full_name":"r12f/divoom","owner":"r12f","description":"Rust Library for controlling divoom devices that support REST APIs, such as pixoo-64.","archived":false,"fork":false,"pushed_at":"2024-01-15T18:10:47.000Z","size":742,"stargazers_count":51,"open_issues_count":5,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-12-06T10:17:14.144Z","etag":null,"topics":["divoom","pixoo","pixoo64","rust","rust-library"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/r12f.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-09T13:58:26.000Z","updated_at":"2024-11-03T22:33:30.000Z","dependencies_parsed_at":"2024-01-15T20:00:31.191Z","dependency_job_id":"5141d77d-ba9f-47e3-a78e-8fd149ce1689","html_url":"https://github.com/r12f/divoom","commit_stats":{"total_commits":161,"total_committers":2,"mean_commits":80.5,"dds":0.006211180124223614,"last_synced_commit":"b1048f809a875d2eb9d6397d4b45f8d4af2ca497"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r12f%2Fdivoom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r12f%2Fdivoom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r12f%2Fdivoom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r12f%2Fdivoom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/r12f","download_url":"https://codeload.github.com/r12f/divoom/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230527866,"owners_count":18240051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["divoom","pixoo","pixoo64","rust","rust-library"],"created_at":"2024-11-06T08:36:13.622Z","updated_at":"2024-12-20T03:10:00.148Z","avatar_url":"https://github.com/r12f.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Divoom\n![Divoom](https://raw.githubusercontent.com/r12f/divoom/main/assets/Logo.png)\n\nRust Library for controlling divoom devices that support REST APIs, such as pixoo-64 (and from how divoom's api/doc organizes, maybe more in the future).\n\n[![Crates.io](https://img.shields.io/crates/v/divoom)](https://crates.io/crates/divoom)\n[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/r12f/divoom?color=blue\u0026label=github%20release\u0026style=flat-square)](https://github.com/r12f/divoom/releases)\n[![Documentation](https://docs.rs/divoom/badge.svg)](https://docs.rs/divoom/)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE-APACHE)\n[![Build Status](https://riff.visualstudio.com/divoom/_apis/build/status/r12f.divoom?branchName=main)](https://riff.visualstudio.com/divoom/_build/latest?definitionId=7\u0026branchName=main)\n\n```rust\n// Get current channel\nuse divoom::*;\n\nprintln!(\n    \"{}\",\n    PixooClient::new(\"192.168.0.123\").get_current_channel().await?\n);\n\n// Output: clock\n```\n\nBesides the SDK, a few more tools are provided to help people enjoy the device as well as serving as demo! \n- A command line tool `divoom-cli` for controlling the device: \u003chttps://github.com/r12f/divoom/tree/main/divoom_cli\u003e.\n  ```bash\n  # Check current channel\n  \u003e divoom-cli 192.168.0.123 channel get\n  ---\n  clock\n  ```\n\n- A REST gateway `divoom-gateway` with Swagger UI and OpenAPI spec json provided, so we can control the device, build cron-like schedule, render customized animation and play it on the device: \u003chttps://github.com/r12f/divoom/tree/main/divoom_gateway\u003e.\n\n## How to use\n\nTo use this library, please add the following into the dependencies in the `Cargo.toml` file:\n\n```toml\n[dependencies]\ndivoom = \"0.1\"\n```\n\nThe library contains 2 major parts:\n\n- Divoom service APIs, that is used for talking to Divoom's backend service for device discovery etc.\n- Pixoo device APIs, that is used for talking to a specific device via its REST APIs.\n\n### Divoom service APIs\n\nTo discover all devices in your LAN, we can use the `get_same_lan_devices` API to get all devices from Divoom's backend service.\n\n```rust\nuse divoom::*;\n\nlet divoom = DivoomServiceClient::new();\nlet devices = divoom.get_same_lan_devices().await?;\ndevices.iter().for_each(|x| println!(\"{:?}\", x));\n```\n\nThis will output:\n\n```text\nDivoomDeviceInfo { device_name: \"Pixoo\", device_id: 300000001, device_private_ip: \"192.168.0.123\" }\n```\n\n### Pixoo device APIs\n\nOnce we get the Device Address, we can use it to create a pixoo client and start talking to it:\n\n```rust\nuse divoom::*;\n\nlet pixoo = PixooClient::new(\"192.168.0.123\");\nlet result = pixoo.get_current_channel().await?;\nprintln!(\"{:?}\", result);\n```\n\nThis will output:\n```text\nClock\n```\n\nCurrently, we have these APIs supported:\n\n- Channel APIs\n    - [x] Select channel\n    - [x] Get current channel\n    - [x] Select clock\n    - [x] Get selected clock info\n    - [x] Select cloud channel\n    - [x] Select visualizer\n    - [x] Select custom page\n- System/Device APIs\n    - [x] Get device settings\n    - [x] Get device time\n    - [x] Set device brightness\n    - [x] Set device time\n    - [x] Set device high light mode\n    - [x] Set device hour mode\n    - [x] Set device mirror mode\n    - [x] Set device rotation angle\n    - [x] Set device screen power state\n    - [x] Set device temperature unit\n    - [x] Set device time zone\n    - [x] Set device weather area\n    - [x] Set device white balance\n- Tools APIs\n    - [x] Set countdown tool\n    - [x] Set noise tool\n    - [x] Set scoreboard tool\n    - [x] Set stopwatch tool\n- Animation APIs\n    - [x] Play gif from file\n    - [x] Get next animation id\n    - [x] Reset next animation id\n    - [x] Send image animation\n    - [x] Send text animation\n    - [x] Clear all text area\n    - [x] Play buzzer\n- Batch APIs\n    - [X] Batching commands\n    - [X] Execute commands from url\n\n#### Image Animation\n\nDevices like Pixoo-64 supports play GIF file from file or even Internet directly, all we need is to specify a URL as below:\n\n```rust\nuse divoom::*;\n\nlet pixoo = PixooClient::new(\"192.168.0.123\");\npixoo.play_gif_file(DivoomFileAnimationSourceType::Url, \"\u003cSome URL goes here\u003e\").await?;\n```\n\nHowever, this device API is not quite stable (by 07/2022) and the most reliable way to play a GIF is to create an animation and draw\nall the GIF frames into it one by one. To help with this process, we created a resource loader and an animation builder to help.\n\n```rust\nuse divoom::*;\n\n// Load the resource.\nlet frames = DivoomAnimationResourceLoader::gif_file(\"test_data/animation_builder_tests/logo-16-rotate-4-frames.gif\").unwrap();\n\n// Build animation with 16 pixel canvas and 100ms frame play speed.\nlet builder = DivoomAnimationBuilder::new(16, Duration::from_millis(100)).unwrap();\nlet animation = builder.draw_frames(\u0026frames, 0).build();\n\n// Send to device here.\nlet pixoo = PixooClient::new(\"192.168.0.123\");\npixoo.send_image_animation(animation).await\n```\n\nOr even simpler:\n\n```rust\nuse divoom::*;\nlet pixoo = PixooClient::new(\"192.168.0.123\");\npixoo.render_gif_as_animation(16, Duration::from_millis(100), \"test_data/animation_builder_tests/logo-16-rotate-4-frames.gif\").await\n```\n\nBesides gif, we also support png and jpeg format. And besides reading from file, we also support loading resource from any `Read` trait. For more on how to use it, feel free to check our doc here: \u003chttps://docs.rs/divoom/latest/divoom/struct.DivoomAnimationBuilder.html\u003e.\n\nAnd for any reason, if you don't want the builtin animation builder, we can exclude it by specifying the features with:\n\n```toml\n[dependencies]\ndivoom = { version = \"0.1\", features = [] }\n```\n\n#### Text Animation\n\nTo create a text animation, we can use `DivoomTextAnimation` structure and `send_text_animation` API to help us:\n\n```rust\nuse divoom::*;\n\nlet pixoo = PixooClient::new(\"192.168.0.123\");\nlet animation = DivoomTextAnimation::default(); \nanimation.text_string = \"Foo\".to_string();\npixoo.send_text_animation(animation).await?;\n```\n\n#### Command batching\n\nIn certain cases, we might want to run a lot of commands at the same time, such as initialize the settings. Pixoo devices supports batching all commands into a single request, but with only 1 single result being returned for indicating if everything succeeded or not.\n\nHere is an example that we batch executed multiple commands to update the device settings:\n\n```rust\nuse divoom::*;\nlet pixoo = PixooClient::new(\"192.168.0.123\");\npixoo.start_batch()\n  .set_device_rotation_angle(DivoomDeviceRotationAngle::Rotate90)\n  .set_device_mirror_mode(DivoomDeviceMirrorMode::On)\n  .set_device_brightness(30)\n  .execute().await.expect(\"Request should succeed.\");\n```\n\n#### Sending raw requests\n\nIn case new API is released and we haven't support it yet, or we need to do some experimental things by sending the raw payload, we can use the following API to send raw request directly, which works for both single request and batch mode.\n\nSingle request mode:\n\n```rust\nuse divoom::*;\n\nlet pixoo = PixooClient::new(\"192.168.0.123\");\npixoo.send_raw_request(\"{ \\\"Command\\\": \\\"Device/SetHighLightMode\\\", \\\"Mode\\\": 0 }\").await?.expect(\"Request should succeed.\");\n```\n\nBatch mode:\n\n```rust\nuse divoom::*;\nlet pixoo = PixooClient::new(\"192.168.0.123\");\npixoo.start_batch()\n  .send_raw_request(\"{ \\\"Command\\\": \\\"Device/SetHighLightMode\\\", \\\"Mode\\\": 0 }\".into())\n  .execute_with_raw_response().await.expect(\"Request should succeed.\");\n```\n\n## Debugging\n\nThe debug logs are logged at debug level. Once we set the log level to debug, we will be able to start see it:\n\n```rust\nenv_logger::Builder::from_env(env_logger::Env::default().default_filter_or(\"debug\")).init();\n```\n\nOr we can use `RUST_LOG` environment variable to change the level and enable the logs:\n\nWith the command tool (covered below soon), on windows:\n\n```powershell\n\u003e $env:RUST_LOG=\"debug\"; .\\divoom-cli.exe 192.168.0.123 channel get\n```\n\nAnd on linux:\n\n```bash\nRUST_LOG=debug ./divoom-cli.exe 192.168.0.123 channel get\n```\n\nThen we will see the output log like below:\n\n```text\n[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\"}\"\n[2022-07-10T00:33:50Z DEBUG reqwest::connect] starting new connection: http://192.168.0.123/\n[2022-07-10T00:33:50Z DEBUG hyper::client::connect::http] connecting to 192.168.0.123:80\n[2022-07-10T00:33:50Z DEBUG hyper::client::connect::http] connected to 192.168.0.123:80\n[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::io] flushed 107 bytes\n[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::io] parsed 2 headers\n[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::conn] incoming body is chunked encoding\n[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::decode] incoming chunked header: 0x22 (34 bytes)\n[2022-07-10T00:33:50Z DEBUG reqwest::async_impl::client] response '200 OK' for http://192.168.0.123/post\n[2022-07-10T00:33:50Z DEBUG divoom::clients::common::divoom_rest_client] Response header received: StatusCode = 200\n[2022-07-10T00:33:50Z DEBUG hyper::proto::h1::conn] incoming body completed\n[2022-07-10T00:33:50Z DEBUG hyper::client::pool] pooling idle connection for (\"http\", 192.168.0.123)\n[2022-07-10T00:33:50Z DEBUG divoom::clients::common::divoom_rest_client] Response received: Body = \"{\"error_code\": 0, \"SelectIndex\":3}\"\n---\ncustomPage\n```\n\nTo revert it back:\n```powershell\n\u003e $env:RUST_LOG=\"warn\"; .\\divoom-cli.exe 192.168.0.123 channel get\n---\ncustomPage\n```\n\n# Acknowledgements\n\n- Thanks to [@farique1](https://github.com/farique1) for allowing me to bundle the classic 8-bits fonts, that generated via his nice project\n  [Chartotype](https://github.com/farique1/Chartotype), as part of the [Divoom Gateway](https://github.com/r12f/divoom/tree/main/divoom_gateway), which\n  helps generate text animations.\n\n## License\nApache-2.0: \u003chttps://www.apache.org/licenses/LICENSE-2.0\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr12f%2Fdivoom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fr12f%2Fdivoom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr12f%2Fdivoom/lists"}