Quick Start Example
A minimal example to get started:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a new client
let mut client = Growatt::new();
// Login
if client.login("your_username", "your_password").await? {
println!("Login successful!");
// Get plants
let plants = client.get_plants().await?;
println!("Plants: {:?}", plants);
// When you're done
client.logout().await?;
}
Ok(())
}
Environment Variables Configuration
Initialize the client using environment variables:use growatt::Growatt;
use dotenv::dotenv;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load from .env file and environment
dotenv().ok();
// Create client with env vars (GROWATT_USERNAME, GROWATT_PASSWORD, etc.)
let mut client = Growatt::from_env();
// Auto-login using credentials from environment
if let (Some(username), Some(password)) = (
std::env::var("GROWATT_USERNAME").ok(),
std::env::var("GROWATT_PASSWORD").ok(),
) {
client.login(&username, &password).await?;
// Your code here
let plants = client.get_plants().await?;
println!("Found {} plants", plants.0.len());
client.logout().await?;
}
Ok(())
}
.env File Format
GROWATT_USERNAME=your_username
GROWATT_PASSWORD=your_password
GROWATT_BASE_URL=https://server.growatt.com # Optional
GROWATT_SESSION_DURATION=30 # Optional, in minutes
Complete Plant Information Example
Fromsrc/main.rs - iterate over all plants and retrieve detailed information:
use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize the Growatt client
let mut client = Growatt::new();
// Replace these with your actual credentials
let username = "your_username";
let password = "your_password";
// Login to the Growatt API
match client.login(username, password).await {
Ok(true) => {
println!("Login successful!");
// Get the list of plants
match client.get_plants().await {
Ok(plants) => {
println!("Found {} plants:", plants.0.len());
// Display information about each plant
for plant in plants.0 {
println!("Plant ID: {}", plant.plant_id);
println!("Plant Name: {}", plant.plant_name);
if let Some(address) = plant.plant_address {
println!("Address: {}", address);
}
if let Some(power) = plant.plant_watts {
println!("Power (W): {}", power);
}
println!("-------------------");
// Optional: Get more detailed data for each plant
match client.get_plant(&plant.plant_id).await {
Ok(plant_data) => {
println!("Additional plant data:");
if let Some(capacity) = plant_data.capacity {
println!("Capacity: {}", capacity);
}
if let Some(today_energy) = plant_data.today_energy {
println!("Today's Energy: {}", today_energy);
}
if let Some(total_energy) = plant_data.total_energy {
println!("Total Energy: {}", total_energy);
}
println!("-------------------");
},
Err(e) => println!("Error getting detailed plant data: {}", e),
}
}
},
Err(e) => println!("Error getting plants: {}", e),
}
// Logout when done
if let Err(e) = client.logout().await {
println!("Error during logout: {}", e);
} else {
println!("Successfully logged out");
}
},
Ok(false) => println!("Login failed! Check your credentials."),
Err(e) => println!("Error during login: {}", e),
}
Ok(())
}
Custom Client Configuration
Examples of configuring the client with custom settings:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Use alternative API server
let mut client = Growatt::new().with_alternate_url();
client.login("username", "password").await?;
let plants = client.get_plants().await?;
client.logout().await?;
Ok(());
}
use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Set custom session duration (60 minutes)
let mut client = Growatt::new().with_session_duration(60);
client.login("username", "password").await?;
// Session will remain valid for 60 minutes
let plants = client.get_plants().await?;
client.logout().await?;
Ok(());
}
Energy Statistics Example
Retrieve and display energy statistics:use growatt::Growatt;
use chrono::Local;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
client.login("username", "password").await?;
// Get plants and MIX devices
let plants = client.get_plants().await?;
let plant_id = &plants.0[0].plant_id;
let mix_ids = client.get_mix_ids(plant_id).await?;
// Extract MIX serial number from response
let mix_sn = "your_mix_serial_number";
// Current date components
let now = Local::now();
let today = now.format("%Y-%m-%d").to_string();
let this_month = now.format("%Y-%m").to_string();
let this_year = now.format("%Y").to_string();
// Get daily energy statistics
println!("Daily Statistics for {}:", today);
let daily_stats = client.get_energy_stats_daily(&today, plant_id, mix_sn).await?;
println!("{}", daily_stats);
// Get monthly energy statistics
println!("\nMonthly Statistics for {}:", this_month);
let monthly_stats = client.get_energy_stats_monthly(&this_month, plant_id, mix_sn).await?;
println!("{}", monthly_stats);
// Get yearly energy statistics
println!("\nYearly Statistics for {}:", this_year);
let yearly_stats = client.get_energy_stats_yearly(&this_year, plant_id, mix_sn).await?;
println!("{}", yearly_stats);
// Get total energy statistics
println!("\nTotal Energy Statistics:");
let total_stats = client.get_energy_stats_total(&this_year, plant_id, mix_sn).await?;
println!("{}", total_stats);
client.logout().await?;
Ok(())
}
Device Information Example
Retrieve device and MIX information:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
client.login("username", "password").await?;
let plants = client.get_plants().await?;
let plant_id = &plants.0[0].plant_id;
// Get MIX device IDs
println!("Fetching MIX devices...");
let mix_ids = client.get_mix_ids(plant_id).await?;
println!("MIX devices: {}", mix_ids);
// Get device list
println!("\nFetching device list...");
let devices = client.get_device_list(plant_id).await?;
println!("Devices: {}", devices);
// Get devices with pagination
println!("\nFetching devices (page 1)...");
let devices_page = client.get_devices_by_plant_list(plant_id, Some(1)).await?;
println!("Devices page: {}", devices_page);
// Get MIX status (requires MIX serial number)
let mix_sn = "your_mix_serial_number";
println!("\nFetching MIX status...");
let mix_status = client.get_mix_status(plant_id, mix_sn).await?;
println!("MIX status: {}", mix_status);
// Get MIX total data
println!("\nFetching MIX total data...");
let mix_total = client.get_mix_total(plant_id, mix_sn).await?;
println!("MIX total: {}", mix_total);
client.logout().await?;
Ok(())
}
Fault Logs Example
Retrieve and parse fault logs:use growatt::Growatt;
use chrono::Local;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
client.login("username", "password").await?;
let plant_id = "your_plant_id";
let device_sn = "your_device_serial_number";
let today = Local::now().format("%Y-%m-%d").to_string();
// Get fault logs
// Parameters: plant_id, date (optional), device_sn, page_num, device_flag, fault_type
let fault_logs = client.get_fault_logs(
plant_id,
Some(&today), // Date (None for today)
device_sn,
1, // Page number
0, // Device flag (0 = All)
0 // Fault type (0 = All)
).await?;
println!("Fault logs: {}", fault_logs);
// Alternative method (same functionality)
let fault_logs = client.get_plant_fault_logs(
plant_id,
Some(&today),
device_sn,
1,
0,
0
).await?;
client.logout().await?;
Ok(())
}
Battery Statistics Example
Retrieve battery charge/discharge statistics:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
client.login("username", "password").await?;
let plant_id = "your_plant_id";
let mix_sn = "your_mix_serial_number";
// Get weekly battery statistics
println!("Fetching battery statistics...");
let battery_stats = client.get_weekly_battery_stats(plant_id, mix_sn).await?;
println!("Battery statistics: {}", battery_stats);
client.logout().await?;
Ok(())
}
Weather Information Example
Retrieve weather data for a plant:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
client.login("username", "password").await?;
let plants = client.get_plants().await?;
for plant in plants.0 {
println!("Weather for plant: {}", plant.plant_name);
match client.get_weather(&plant.plant_id).await {
Ok(weather) => println!("Weather data: {}", weather),
Err(e) => eprintln!("Error getting weather: {}", e),
}
println!("-------------------");
}
client.logout().await?;
Ok(())
}
Comprehensive Error Handling Example
Robust error handling for production use:use growatt::{Growatt, GrowattError};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
let username = "your_username";
let password = "your_password";
// Handle login errors
match client.login(username, password).await {
Ok(true) => println!("Login successful!"),
Ok(false) => {
eprintln!("Login failed! Check your credentials.");
return Ok(());
},
Err(err) => match err {
GrowattError::AuthError(msg) => {
eprintln!("Authentication error: {}", msg);
return Ok(());
},
GrowattError::RequestError(err) => {
eprintln!("Network error: {}", err);
return Ok(());
},
GrowattError::JsonError(err) => {
eprintln!("JSON parsing error: {}", err);
return Ok(());
},
GrowattError::InvalidResponse(msg) => {
eprintln!("Invalid API response: {}", msg);
return Ok(());
},
GrowattError::NotLoggedIn => {
eprintln!("Not logged in");
return Ok(());
}
}
}
// Handle API call errors
match client.get_plants().await {
Ok(plants) => {
println!("Found {} plants:", plants.0.len());
for plant in plants.0 {
println!("- {}: {}", plant.plant_id, plant.plant_name);
}
},
Err(e) => eprintln!("Error getting plants: {}", e),
}
// Logout gracefully
if let Err(e) = client.logout().await {
eprintln!("Error during logout: {}", e);
} else {
println!("Successfully logged out");
}
Ok(())
}
MIX Device Control Example
Update MIX device settings:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
client.login("username", "password").await?;
let plant_id = "your_plant_id";
let mix_sn = "your_mix_serial_number";
// Update MIX AC discharge time period to current time
println!("Updating MIX discharge time period...");
let result = client.post_mix_ac_discharge_time_period_now(plant_id, mix_sn).await?;
println!("Update result: {}", result);
client.logout().await?;
Ok(())
}
Session Management Example
Demonstrate automatic session renewal:use growatt::Growatt;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new()
.with_session_duration(1); // 1 minute session for testing
client.login("username", "password").await?;
println!("Initial login successful");
// First API call - should work with active session
let plants = client.get_plants().await?;
println!("First call: Found {} plants", plants.0.len());
// Wait for session to expire
println!("Waiting for session to expire...");
sleep(Duration::from_secs(70)).await;
// Second API call - should automatically re-authenticate
let plants = client.get_plants().await?;
println!("Second call (after session expiry): Found {} plants", plants.0.len());
println!("SDK automatically re-authenticated!");
client.logout().await?;
Ok(())
}
Token Access Example
Access the authentication token:use growatt::Growatt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Growatt::new();
// Before login, token is None
assert!(client.get_token().is_none());
// Login
client.login("username", "password").await?;
// After login, token may be available (if API provides it)
if let Some(token) = client.get_token() {
println!("Authentication token: {}", token);
// Use token for external purposes if needed
} else {
println!("No token provided by API");
}
// Check login status
println!("Is logged in: {}", client.is_logged_in());
client.logout().await?;
// After logout, status changes
println!("Is logged in: {}", client.is_logged_in());
Ok(())
}