Skip to main content
The PlantData struct represents comprehensive information about a specific solar plant, including energy production metrics and current operational status.

Structure

#[derive(Debug, Serialize, Deserialize)]
pub struct PlantData {
    #[serde(rename = "plantName")]
    pub plant_name: Option<String>,
    #[serde(rename = "plantId")]
    pub plant_id: Option<String>,
    #[serde(rename = "capacity")]
    pub capacity: Option<f64>,
    #[serde(rename = "todayEnergy")]
    pub today_energy: Option<f64>,
    #[serde(rename = "totalEnergy")]
    pub total_energy: Option<f64>,
    #[serde(rename = "currentPower")]
    pub current_power: Option<f64>,
}
This struct is defined in src/lib.rs:52-67 and represents the detailed data returned by the Growatt API for a specific plant.

Fields

All fields in PlantData are optional (Option<T>) as the API may not return all data points depending on the plant’s configuration or current status.
plant_name
Option<String>
Name of the plant. Serialized as "plantName" in the API.
plant_id
Option<String>
Unique identifier for the plant. Serialized as "plantId" in the API.
capacity
Option<f64>
Total installed capacity of the plant, typically in kilowatts (kW).
today_energy
Option<f64>
Energy produced today in kilowatt-hours (kWh). Serialized as "todayEnergy" in the API.
total_energy
Option<f64>
Cumulative total energy produced since installation in kilowatt-hours (kWh). Serialized as "totalEnergy" in the API.
current_power
Option<f64>
Current power output in watts (W). Serialized as "currentPower" in the API.

Usage Example

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 = "12345";
    
    // Get detailed plant data
    let plant_data = client.get_plant(plant_id).await?;
    
    // Access fields with safe unwrapping
    if let Some(name) = plant_data.plant_name {
        println!("Plant: {}", name);
    }
    
    if let Some(capacity) = plant_data.capacity {
        println!("Capacity: {} kW", capacity);
    }
    
    if let Some(today) = plant_data.today_energy {
        println!("Today's Energy: {} kWh", today);
    }
    
    if let Some(total) = plant_data.total_energy {
        println!("Total Energy: {} kWh", total);
    }
    
    if let Some(power) = plant_data.current_power {
        println!("Current Power: {} W", power);
    }
    
    Ok(())
}

Handling Optional Fields

Since all fields are optional, you should use pattern matching or the Option API methods:
// Using if let
if let Some(energy) = plant_data.today_energy {
    println!("Today: {} kWh", energy);
} else {
    println!("Today's energy data not available");
}

// Using unwrap_or for defaults
let current = plant_data.current_power.unwrap_or(0.0);

// Using map for transformations
let efficiency = plant_data.capacity
    .and_then(|cap| plant_data.current_power.map(|pow| (pow / (cap * 1000.0)) * 100.0));

if let Some(eff) = efficiency {
    println!("Current efficiency: {:.2}%", eff);
}

Calculating Metrics

You can combine fields to calculate useful metrics:
// Calculate capacity factor for today
if let (Some(today_energy), Some(capacity)) = 
    (plant_data.today_energy, plant_data.capacity) {
    let capacity_factor = (today_energy / (capacity * 24.0)) * 100.0;
    println!("Today's capacity factor: {:.2}%", capacity_factor);
}

// Check if plant is currently producing
if let Some(current_power) = plant_data.current_power {
    if current_power > 0.0 {
        println!("Plant is actively producing power");
    } else {
        println!("Plant is idle");
    }
}

Difference from Plant

The Plant struct contains basic identification and configuration information, while PlantData provides operational metrics and energy statistics:
PlantPlantData
Basic info (ID, name, address)Energy metrics
Static dataDynamic/current data
Returned by get_plants()Returned by get_plant()
All plants at onceSingle plant details
  • get_plant() - Retrieves PlantData for a specific plant
  • get_plants() - Retrieves list of all plants (returns Plant, not PlantData)
The API may add additional fields in the future. The comment in the source code (// Add more fields as needed based on the actual API response) indicates this struct may be extended.

Build docs developers (and LLMs) love