Metadata-Version: 2.4
Name: sig-cloud-control
Version: 0.3.2
Summary: Control Sigenergy battery via Sigen Cloud
Project-URL: Homepage, https://github.com/lawther/sig-cloud-control
Project-URL: Repository, https://github.com/lawther/sig-cloud-control
Project-URL: Issues, https://github.com/lawther/sig-cloud-control/issues
Author-email: Mike Lawther <mike.lawther@gmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: battery,energy-storage,iot,sigen,sigenergy,solar
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Home Automation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: cryptography~=46.0
Requires-Dist: httpx~=0.28
Requires-Dist: platformdirs>=4.0
Requires-Dist: pydantic-settings>=2.14.0
Requires-Dist: pydantic[email]~=2.12
Requires-Dist: tomli-w>=1.2.0
Requires-Dist: typer~=0.24
Description-Content-Type: text/markdown

# sig-cloud-control

A Python library and CLI for controlling Sigenergy (Sigen Cloud) solar and battery systems.

> [⚠️ CAUTION]
> **Non-Affiliation**
> - **Not Official:** This project is not affiliated with, authorised by, or endorsed by Sigenergy. Use of this tool is at your own risk.
> - **Warranty Warning:** Using this tool may violate your Sigenergy Terms of Service and could potentially void your hardware warranty. The author is not responsible for any loss of warranty or damage to equipment.
> - **Reverse Engineering:** This tool was developed for the purpose of interoperability between Sigenergy batteries and third-party automation systems.

## Compatibility

The following Sigen Cloud regional data centres are supported:

| Region | Value | API Base URL |
|--------|-------|-------------|
| Australia / New Zealand | `aus` | `api-aus.sigencloud.com` |
| Asia-Pacific (rest) | `apac` | `api-apac.sigencloud.com` |
| Europe | `eu` | `api-eu.sigencloud.com` |
| China | `cn` | `api-cn.sigencloud.com` |
| United States | `us` | `api-us.sigencloud.com` |

## Operations

- `charge`: Force charge the battery from the grid for a specified duration.
- `discharge`: Force discharge the battery for a specified duration.
- `hold`: Hold the battery at its current state of charge for a specified duration.
- `self-consumption`: Enable self-consumption mode for a specified duration. The battery prioritises consuming solar generation.
- `cancel`: Immediately return the battery to its configured default mode (which may be self-consumption, VPP control, or another mode set by your installer).

> **`self-consumption` vs `cancel`:** Use `self-consumption` to explicitly activate solar-first behaviour for a set period. Use `cancel` to immediately hand control back to the battery's configured default, whatever that may be.

## Installation

### From PyPI (Recommended)

```bash
pip install sig-cloud-control
# or using uv
uv tool install sig-cloud-control
```

### From Source (Development)

This project uses `uv` for dependency management.

```bash
# Clone the repository
git clone https://github.com/lawther/sig-cloud-control.git
cd sig-cloud-control

# Install dependencies
uv sync
```

## Configuration

### Interactive Setup (Recommended for local use)

```bash
sig-cloud-control setup
```

This prompts for your credentials, encrypts your password, and saves a config file to the platform default location:

- **macOS/Linux:** `~/.config/sig-cloud-control/config.toml`
- **Windows:** `%LOCALAPPDATA%\sig-cloud-control\sig-cloud-control\config.toml`

### Config File Discovery

When no `--config` flag is provided, the tool searches for a config file in this order:

1. `./config.toml` in the current directory (for project-local use)
2. The platform default location above

### Environment Variables (Recommended for Docker/CI)

Environment variables take precedence over the configuration file:

- `SIGEN_USERNAME`: Your Sigen Cloud email address.
- `SIGEN_PASSWORD_ENCODED`: Your encrypted password (generate with `sig-cloud-control setup`).
- `SIGEN_PASSWORD`: Your plaintext password (convenient for CI secrets).
- `SIGEN_STATION_ID`: Your Station ID (optional).
- `SIGEN_REGION`: Your regional data centre (e.g. `aus`, `eu`, `us`). See [Compatibility](#compatibility) for all values.

### Config File Format

```toml
username = "example@example.com"

# Use the encrypted password (generated by `sig-cloud-control setup`):
password_encoded = "..."

# OR use a plaintext password:
# password = "your_plaintext_password"

# region is required. Supported values: aus, apac, eu, cn, us
region = "aus"

# station_id is optional and will be fetched automatically if omitted.
# Find it in the Sigen app under Settings -> System Settings -> About.
# station_id = 12345
```

## CLI Usage

```bash
# Setup credentials interactively (saves to platform default config location)
sig-cloud-control setup

# Charge battery for 60 minutes at 2.5 kW (charge rate limit)
sig-cloud-control charge 60 --power 2.5

# Discharge battery for 30 minutes at maximum rate
sig-cloud-control discharge 30

# Hold battery at current state of charge for 60 minutes
sig-cloud-control hold 60

# Enable self-consumption mode for 30 minutes
sig-cloud-control self-consumption 30

# Return battery to its default mode immediately
sig-cloud-control cancel

# Use a specific config file
sig-cloud-control charge 60 --config /path/to/config.toml

# Enable verbose logging for debugging
sig-cloud-control charge 60 --verbose
```

### Options

| Option | Description |
|--------|-------------|
| `--power` | Charge/discharge rate limit in kW (supported by `charge` and `discharge` only) |
| `--config` | Path to the TOML configuration file |
| `--verbose`, `-v` | Enable verbose debug logging to stderr |

## API Usage

You can use `sig-cloud-control` as a library in your own asynchronous Python applications. The public API is exposed at the root level:

```python
import asyncio
from sig_cloud_control import SigCloudClient, Config, Region

async def main():

    config = Config(
        username="user@example.com",
        password="my_secret_password",
        region=Region.AUS,
    )

    # Use as an async context manager — handles cleanup automatically
    async with SigCloudClient(config) as client:
        await client.login()
        await client.charge_battery(duration_min=60, power_kw=5.0)
        print("Charge command issued successfully.")

if __name__ == "__main__":
    asyncio.run(main())
```

### Token Cache

By default, `SigCloudClient` caches authentication tokens at the platform cache directory (e.g. `~/.cache/sig-cloud-control/token-cache.json` on Linux). To disable caching, pass `cache_path=None`:

```python
client = SigCloudClient(config, cache_path=None)
```

### Error Handling

All errors are subclasses of `SigCloudError`. Import the specific types for finer-grained handling:

```python
from sig_cloud_control import AuthenticationError, StationError, APIError, SigCloudError

async with SigCloudClient(config) as client:
    try:
        await client.login()
    except AuthenticationError:
        print("Bad credentials — check username/password.")
    except StationError:
        print("Could not resolve station ID.")
    except APIError:
        print("Unexpected API response.")
    except SigCloudError:
        print("Other Sigen Cloud error.")
```

| Exception | When raised |
|-----------|-------------|
| `AuthenticationError` | Login failed (bad credentials or token error) |
| `StationError` | Station ID could not be resolved or is unknown |
| `APIError` | Sigen API returned an unexpected or unparseable response |
| `SigCloudError` | Base class; also raised for pre-condition failures (e.g. invalid duration) |

## Development

This project uses `just` to manage development tasks. The `Justfile` is the Single Source Of Truth (SSOT) for all pre-commit checks and development workflows. No additional linting or testing logic should be added anywhere else (e.g. CI configs).

### Help

```bash
just
```

### Running Pre-commit Checks (Lint + Test)

```bash
just precommit
```

### Running Tests

```bash
just test
```

### Linting and Formatting

```bash
just lint
```

## License

Apache 2.0
