xplorer_rs/lib.rs
1#![warn(missing_docs)]
2#![deny(unsafe_code)]
3
4//! # xplorer-rs
5//!
6//! Control library for X-Plorer Serie 75 S / Serie 95 S robot vacuum cleaners.
7//!
8//! Built on top of [`tuya_rs`] for Tuya v3.3 protocol communication. Provides
9//! high-level commands (room cleaning, zone cleaning, forbidden zones, virtual walls)
10//! and map file decoding (layout + route).
11//!
12//! Two implementations of the [`Device`] trait are available:
13//!
14//! - [`LocalXPlorer`] — local TCP control via the Tuya v3.3 protocol (default)
15//! - [`CloudXPlorer`] — cloud control via the Tuya OEM Mobile API (`cloud` feature)
16//!
17//! ## Quick start (local)
18//!
19//! ```no_run
20//! # async fn example() {
21//! use xplorer_rs::{LocalXPlorer, Device, DeviceConfig};
22//! use xplorer_rs::protocol::{RoomCleanCommand, Zone, ZoneCleanCommand};
23//!
24//! let config = DeviceConfig {
25//! dev_id: "device_id_here".into(),
26//! address: "192.168.1.100".into(),
27//! local_key: "0123456789abcdef".into(),
28//! ..Default::default()
29//! };
30//! let mut robot = LocalXPlorer::connect(&config).unwrap();
31//!
32//! // Check status
33//! let state = robot.status().await.unwrap();
34//! println!("battery: {}%, mode: {}", state.battery, state.mode);
35//!
36//! // Clean specific rooms (1 pass, rooms 0 and 2)
37//! robot.clean_rooms(&RoomCleanCommand {
38//! clean_times: 1,
39//! room_ids: vec![0, 2],
40//! }).await.unwrap();
41//!
42//! // Or clean a rectangular zone
43//! robot.clean_zone(&ZoneCleanCommand {
44//! clean_times: 1,
45//! zones: vec![Zone::rect(82, -13, 453, 203)],
46//! }).await.unwrap();
47//! # }
48//! ```
49//!
50//! ## Quick start (cloud)
51//!
52//! ```no_run
53//! # #[cfg(feature = "cloud")]
54//! # async fn example() {
55//! use xplorer_rs::{CloudXPlorer, Device, xplorer_oem_credentials};
56//!
57//! let oem_creds = xplorer_oem_credentials("your_44char_hex_app_device_id_here");
58//! let mut robot = CloudXPlorer::login(oem_creds, "you@email.com", "password", "your_device_id")
59//! .await.unwrap();
60//! let state = robot.status().await.unwrap();
61//! println!("battery: {}%, mode: {}", state.battery, state.mode);
62//! # }
63//! ```
64//!
65//! ## Parsing device events
66//!
67//! ```
68//! use xplorer_rs::device::parse_dps_response;
69//! use xplorer_rs::types::DpsEvent;
70//!
71//! let json = r#"{"dps":{"1":true,"4":"smart","8":72}}"#;
72//! let events = parse_dps_response(json).unwrap();
73//! for event in &events {
74//! match event {
75//! DpsEvent::Battery(pct) => println!("battery: {pct}%"),
76//! DpsEvent::Mode(mode) => println!("mode: {mode}"),
77//! _ => {}
78//! }
79//! }
80//! ```
81//!
82//! ## Decoding sweeper messages
83//!
84//! The robot sends binary commands on DP 15 as base64. Decode them with
85//! [`protocol::SweeperMessage`]:
86//!
87//! ```
88//! use xplorer_rs::protocol::SweeperMessage;
89//!
90//! let msg = SweeperMessage::decode_base64("qgAEFQEBBBs=").unwrap();
91//! assert_eq!(msg.cmd, 0x15); // room clean status
92//! assert!(msg.checksum_ok);
93//! ```
94//!
95//! ## Features
96//!
97//! - **Default**: local TCP control, map decoding (LZ4-compressed layout + route)
98//! - **`cloud`**: cloud API access (login, device discovery, map download via AWS STS),
99//! [`CloudXPlorer`] for remote device control
100//! - **`render`**: PNG rendering of layout maps and cleaning routes
101
102/// Cloud-based vacuum control via Tuya OEM API.
103#[cfg(feature = "cloud")]
104pub mod cloud_device;
105/// Vacuum cleaner device control: [`Device`] trait, [`LocalXPlorer`] (local TCP).
106pub mod device;
107/// Map file decoder (layout + route) with optional PNG rendering.
108pub mod map;
109/// DP 15 binary sweeper protocol: room/zone clean, forbidden zones, virtual walls.
110pub mod protocol;
111/// Device state model: DPS event parsing and enum types.
112pub mod types;
113
114// Re-export for convenience
115pub use device::{Device, LocalXPlorer};
116pub use tuya_rs;
117pub use tuya_rs::connection::{DeviceConfig, DeviceError, DpValue, DpsUpdate, Transport};
118pub use tuya_rs::discovery;
119
120#[cfg(feature = "cloud")]
121pub use cloud_device::{CloudXPlorer, cloud_discover};
122#[cfg(feature = "cloud")]
123pub use device::xplorer_oem_credentials;
124#[cfg(feature = "cloud")]
125pub use tuya_rs::api::{DeviceInfo, Home, StorageCredentials, generate_presigned_url};