Skip to main content

Overview

The Growatt SDK automatically manages session state, including expiry tracking and automatic re-authentication. This ensures your API calls continue to work seamlessly even when sessions expire.

Session Duration

By default, sessions last for 30 minutes. You can customize this duration when creating the client.

Default Duration

let client = Growatt::new();
// Default: 30 minute session duration

Custom Duration

// Set a custom session duration (60 minutes)
let client = Growatt::new().with_session_duration(60);

Via Environment Variable

# .env file
GROWATT_SESSION_DURATION=45  # 45 minutes
use growatt::Growatt;
use dotenv::dotenv;

#[tokio::main]
async fn main() {
    dotenv().ok();
    let client = Growatt::from_env();
    // Session duration set from GROWATT_SESSION_DURATION
}

Session State Methods

is_logged_in()

Check the current authentication status.

Signature

pub fn is_logged_in(&self) -> bool

Returns

bool
bool
Returns true if a session exists, false otherwise. Does not validate session expiry.

Example

if client.is_logged_in() {
    println!("Client has an active session");
} else {
    println!("Client is not logged in");
}
is_logged_in() only checks if a session was established. It does not validate whether the session has expired. Use is_session_valid() for expiry checks.

is_session_valid()

Validates whether the current session has expired.

Signature

fn is_session_valid(&self) -> bool

Returns

bool
bool
Returns true if session exists and has not expired, false otherwise

Behavior

  • Compares current time with session expiry timestamp
  • Returns false if no session expiry is set
  • Does not make network requests
is_session_valid() is a private method used internally. It checks session expiry based on the local timestamp, not server state.

ensure_session()

Ensures a valid session exists, automatically re-authenticating if needed.

Signature

async fn ensure_session(&mut self) -> Result<()>

Returns

Result<()>
Result<()>
Returns Ok(()) if session is valid or re-authentication succeeded, Err(GrowattError::NotLoggedIn) if no credentials are stored

Behavior

  • Checks if session is logged in and valid
  • If session is invalid or expired, attempts to re-authenticate using stored credentials
  • Returns error if no credentials were stored (manual login() required)
  • Called automatically by all API methods before making requests
ensure_session() is a private method called internally by all API methods. You don’t need to call it manually.

Automatic Session Renewal

All API methods automatically check and renew sessions before making requests. This is handled by the internal check_login() method.

How It Works

  1. When you call any API method (e.g., get_plants()), it calls check_login() first
  2. check_login() calls ensure_session()
  3. If the session is expired, ensure_session() automatically re-authenticates using stored credentials
  4. The API request proceeds with a fresh session

Example

use growatt::Growatt;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Growatt::new().with_session_duration(1); // 1 minute for testing
    
    // Initial login
    client.login("username", "password").await?;
    
    // First API call - uses existing session
    let plants = client.get_plants().await?;
    println!("Plants: {:?}", plants);
    
    // Wait for session to expire
    tokio::time::sleep(Duration::from_secs(90)).await;
    
    // Second API call - automatically re-authenticates
    let plants = client.get_plants().await?;
    println!("Plants: {:?}", plants);
    // ^ This succeeds because the SDK automatically renewed the session
    
    Ok(())
}

Session Lifecycle

use growatt::Growatt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Growatt::new();
    
    // 1. No session
    assert!(!client.is_logged_in());
    
    // 2. Login establishes session
    client.login("username", "password").await?;
    assert!(client.is_logged_in());
    
    // 3. Session valid for configured duration (default 30 minutes)
    // All API calls work seamlessly
    let plants = client.get_plants().await?;
    
    // 4. After expiry, automatic renewal on next API call
    // (assuming credentials were stored during login)
    
    // 5. Manual logout terminates session
    client.logout().await?;
    assert!(!client.is_logged_in());
    
    Ok(())
}

Error Scenarios

No Credentials Stored

If the session expires and no credentials were stored, API methods will return an error:
let mut client = Growatt::new();

// Attempting API call without login
match client.get_plants().await {
    Err(GrowattError::NotLoggedIn) => {
        println!("Please login first");
        client.login("username", "password").await?;
    },
    Ok(plants) => println!("Plants: {:?}", plants),
    Err(e) => eprintln!("Error: {}", e),
}

Network Failures During Renewal

match client.get_plants().await {
    Err(GrowattError::RequestError(e)) => {
        eprintln!("Network error during auto-renewal: {}", e);
        // Retry logic here
    },
    Ok(plants) => println!("Success: {:?}", plants),
    Err(e) => eprintln!("Other error: {}", e),
}

Best Practices

Credential Storage: Always use login() with credentials to enable automatic session renewal. This allows the SDK to seamlessly handle expired sessions.
Session Duration: Don’t set session duration too short (< 5 minutes) as it may cause excessive re-authentication requests. The default 30 minutes is recommended for most use cases.
// Good: Credentials stored for auto-renewal
let mut client = Growatt::new();
client.login("username", "password").await?;
// API calls will auto-renew as needed

// Avoid: Manual session management
// The SDK handles this for you automatically

Source Reference

  • is_logged_in() implementation: src/lib.rs:746
  • is_session_valid() implementation: src/lib.rs:228
  • ensure_session() implementation: src/lib.rs:237
  • Session duration configuration: src/lib.rs:96, src/lib.rs:146
  • Auto-renewal in API methods: src/lib.rs:286

Build docs developers (and LLMs) love