Skip to main content

Method Signature

pub async fn get_plant(&mut self, plant_id: &str) -> Result<PlantData>

Description

Retrieves detailed information about a specific solar plant, including current power generation, energy statistics, and capacity. This method automatically handles authentication by checking the current session and re-authenticating if necessary.

Parameters

plant_id
&str
required
The unique identifier of the plant. This ID can be obtained from the get_plants() method.

Return Type

Returns Result<PlantData> where:
  • Success: PlantData - Detailed plant information and statistics
  • Error: GrowattError - See error cases below

PlantData Structure

pub struct PlantData {
    pub plant_name: Option<String>,
    pub plant_id: Option<String>,
    pub capacity: Option<f64>,
    pub today_energy: Option<f64>,
    pub total_energy: Option<f64>,
    pub current_power: Option<f64>,
}

PlantData Fields

plant_name
Option<String>
Name of the plant (mapped from JSON field plantName)
plant_id
Option<String>
Unique identifier for the plant (mapped from JSON field plantId)
capacity
Option<f64>
Total installed capacity of the plant in kilowatts (kW)
today_energy
Option<f64>
Energy generated today in kilowatt-hours (kWh) (mapped from JSON field todayEnergy)
total_energy
Option<f64>
Cumulative energy generated over the plant’s lifetime in kilowatt-hours (kWh) (mapped from JSON field totalEnergy)
current_power
Option<f64>
Current power output in watts (W) (mapped from JSON field currentPower)

Code Examples

Basic Usage

use growatt_api::Growatt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Growatt::new();
    
    // Login first
    client.login("username", "password").await?;
    
    // Get plant details
    let plant_data = client.get_plant("1234567").await?;
    
    // Display plant information
    if let Some(name) = plant_data.plant_name {
        println!("Plant: {}", name);
    }
    
    if let Some(power) = plant_data.current_power {
        println!("Current Power: {:.2} W", power);
    }
    
    if let Some(today) = plant_data.today_energy {
        println!("Today's Energy: {:.2} kWh", today);
    }
    
    if let Some(total) = plant_data.total_energy {
        println!("Total Energy: {:.2} kWh", total);
    }
    
    Ok(())
}

Get Details for All Plants

use growatt_api::Growatt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Growatt::new();
    client.login("username", "password").await?;
    
    // Get list of all plants
    let plants = client.get_plants().await?;
    
    // Fetch detailed data for each plant
    for plant in plants.0.iter() {
        match client.get_plant(&plant.plant_id).await {
            Ok(data) => {
                println!("\n{}", plant.plant_name);
                println!("  Current Power: {:.2} W", 
                         data.current_power.unwrap_or(0.0));
                println!("  Today's Energy: {:.2} kWh", 
                         data.today_energy.unwrap_or(0.0));
            }
            Err(e) => {
                eprintln!("Error fetching data for {}: {}", 
                          plant.plant_name, e);
            }
        }
    }
    
    Ok(())
}

Calculate Efficiency

use growatt_api::Growatt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Growatt::new();
    client.login("username", "password").await?;
    
    let plant_data = client.get_plant("1234567").await?;
    
    // Calculate current efficiency (power vs capacity)
    if let (Some(current_power), Some(capacity)) = 
        (plant_data.current_power, plant_data.capacity) {
        let capacity_watts = capacity * 1000.0; // Convert kW to W
        let efficiency = (current_power / capacity_watts) * 100.0;
        println!("Current efficiency: {:.1}%", efficiency);
    }
    
    Ok(())
}

Monitor Plant in Real-Time

use growatt_api::Growatt;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Growatt::new();
    client.login("username", "password").await?;
    
    let plant_id = "1234567";
    
    // Poll every 5 minutes
    loop {
        match client.get_plant(plant_id).await {
            Ok(data) => {
                println!("[{}] Power: {:.2} W | Today: {:.2} kWh",
                    chrono::Local::now().format("%H:%M:%S"),
                    data.current_power.unwrap_or(0.0),
                    data.today_energy.unwrap_or(0.0)
                );
            }
            Err(e) => {
                eprintln!("Error: {}", e);
            }
        }
        
        sleep(Duration::from_secs(300)).await; // 5 minutes
    }
}

Error Cases

The method may return the following errors:

GrowattError::NotLoggedIn

Thrown when the session is invalid and no credentials are stored for automatic re-authentication.
GrowattError::NotLoggedIn
Solution: Call login() with valid credentials before calling this method.

GrowattError::InvalidResponse (Empty Response)

Thrown when the API returns an empty response or the plant data object is null.
GrowattError::InvalidResponse("Empty response. Please ensure you are logged in.")
Common causes:
  • Invalid plant ID
  • Session expired during the request
  • Plant does not exist or is not accessible to the authenticated user

GrowattError::InvalidResponse (Invalid Structure)

Thrown when the API response does not contain the expected obj field.
GrowattError::InvalidResponse("Invalid response structure")
Common causes:
  • API response format changed
  • Server returned an error response

GrowattError::RequestError

Thrown when the HTTP request fails due to network issues or server problems.
GrowattError::RequestError(reqwest::Error)
Common causes:
  • Network connectivity issues
  • Growatt server is down or unreachable
  • Request timeout

GrowattError::JsonError

Thrown when the response cannot be parsed into the expected PlantData structure.
GrowattError::JsonError(serde_json::Error)
Common causes:
  • API response format changed
  • Unexpected data types in response fields

Implementation Details

API Endpoint

POST {base_url}/panel/getPlantData?plantId={plant_id}
Default base URL: https://server.growatt.com

Response Structure

The API returns a JSON response with the following structure:
{
  "obj": {
    "plantName": "My Solar Plant",
    "plantId": "1234567",
    "capacity": 10.5,
    "todayEnergy": 45.2,
    "totalEnergy": 12500.8,
    "currentPower": 3500.0
  }
}
The method extracts the obj field and deserializes it into the PlantData struct.

Authentication

This method automatically calls check_login() before making the API request, which:
  1. Checks if the current session is valid
  2. Re-authenticates using stored credentials if the session expired
  3. Returns NotLoggedIn error if no credentials are available

Optional Fields

All fields in PlantData are Option<T> types because:
  • The API may not return all fields depending on plant type or configuration
  • Some values may be null during nighttime or when the plant is offline
  • This design allows for flexible handling of partial data

Build docs developers (and LLMs) love