# uniWeather Python Client

Python client for the uniWeather Cloud API - Access IoT weather station and sensor data.

## Installation

```bash
pip install uniweather
```

For pandas DataFrame support:

```bash
pip install uniweather[pandas]
```

For command-line tools with plotting capabilities:

```bash
pip install uniweather[cli]
```

## Quick Start

### Async API (Recommended)

```python
import asyncio
from uniWeather import uniWeatherCloud

async def main():
    client = uniWeatherCloud()
    
    # Connect with your API token
    await client.connect(token="your-api-key-here")
    
    # Get your assigned devices
    devices = await client.my_devices()
    
    # If no assigned devices, get all devices (including unhandled)
    if not devices:
        devices = await client.my_devices(all=True)
    
    if not devices:
        print("No devices found")
        await client.close()
        return
    
    for device in devices:
        print(f"Device: {device.device_id}")
        channels = await client.get_channels(device)
        print(f"Channels: {channels}")
    
    # Query data for the first device (last 7 days)
    from datetime import datetime, timedelta
    data = await client.data(
        device=devices[0],
        channels="all",
        from_date=datetime.now() - timedelta(days=7),
        to_date=datetime.now()
    )
    
    print(f"Retrieved {len(data.channels)} channels")
    
    # Convert to pandas DataFrame (if pandas is installed)
    try:
        df = data.to_dataframe()
        print(df.head())
    except ImportError:
        print("Install pandas to use DataFrame: pip install uniweather[pandas]")
    
    await client.close()

asyncio.run(main())
```

### Synchronous API

```python
from uniWeather import uniWeatherCloudSync

with uniWeatherCloudSync() as client:
    client.connect(token="your-api-key-here")
    devices = client.my_devices()
    data = client.data(devices[0], channels="all")
    df = data.to_dataframe()
    print(df)
```

## Features

### Device Management

```python
# Get assigned/handled devices
devices = await client.my_devices()

# Get all devices (including unhandled)
all_devices = await client.my_devices(all=True)

# Get channels for a device
channels = await client.get_channels(device)
```

### Data Queries

```python
# Using date strings (YYYY-MM-DD)
data = await client.data(device, from_date="2025-05-01", to_date="2025-05-31")

# Using datetime objects
from datetime import datetime
data = await client.data(
    device,
    from_date=datetime(2025, 5, 1),
    to_date=datetime(2025, 5, 31)
)

# Filter specific channels
data = await client.data(device, channels=["temperature", "humidity"])

# Get all channels
data = await client.data(device, channels="all")
```

### Output Formats

#### Pandas DataFrame

```python
data = await client.data(device)
df = data.to_dataframe()
print(df.head())
print(df.describe())

# Plot data
import matplotlib.pyplot as plt
df.plot()
plt.show()
```

#### CSV File

```python
# Download directly to file
await client.download_csv(
    device=device,
    filename="data.csv",
    from_date="2025-05-01",
    to_date="2025-05-31"
)
```

## Command-Line Interface

The package includes a CLI tool for quick data analysis and visualization.

### Installation

```bash
pip install uniweather[cli]
```

### List Devices

List all available devices:

```bash
# Basic list
uniweather list --token YOUR_API_KEY

# List with channels
uniweather list --token YOUR_API_KEY --verbose
```

### Download Data as CSV

Download device data to CSV files:

```bash
# Download all channels (last 24 hours)
uniweather download --token YOUR_API_KEY --device DEVICE_ID --output data.csv

# Download specific channels
uniweather download --token YOUR_API_KEY --device DEVICE_ID --output data.csv \
  --channels "air_temperature,humidity"

# Download last 48 hours with verbose output
uniweather download -t YOUR_API_KEY -d DEVICE_ID -o data.csv --hours 48 --verbose
```

### Plot Temperature

Generate air temperature plots for all devices:

```bash
# Plot last 24 hours (using environment variable for token)
export UNIWEATHER_TOKEN="your-api-key"
uniweather plot-temp --output temperature.pdf

# Plot last 48 hours with verbose output
uniweather plot-temp --token YOUR_API_KEY --hours 48 --output temp.pdf --verbose

# Plot and display interactively
uniweather plot-temp --token YOUR_API_KEY --show

# Save as PNG instead of PDF
uniweather plot-temp --token YOUR_API_KEY --output temp.png --format png
```

### CLI Commands and Options

**List devices:**
```
uniweather list [OPTIONS]

Options:
  --token, -t TOKEN    API authentication token
  --url, -u URL        API base URL (default: https://api.uniweather.io)
  --verbose, -v        Show channels for each device
```

**Download data:**
```
uniweather download [OPTIONS]

Options:
  --token, -t TOKEN         API authentication token
  --url, -u URL             API base URL (default: https://api.uniweather.io)
  --device, -d DEVICE_ID    Device ID to download from (required)
  --output, -o FILE         Output CSV file path (required)
  --channels, -c CHANNELS   Channels to download (comma-separated or "all")
  --hours HOURS             Number of hours to query (default: 24)
  --verbose, -v             Verbose output
```

**Plot temperature:**
```
uniweather plot-temp [OPTIONS]

Options:
  --token, -t TOKEN         API authentication token
  --url, -u URL             API base URL (default: https://api.uniweather.io)
  --hours HOURS             Number of hours to query (default: 24)
  --output, -o OUTPUT       Output file path (e.g., temp.pdf)
  --format, -f FORMAT       Output format: pdf, png, svg (default: pdf)
  --show, -s                Show plot interactively
  --verbose, -v             Verbose output
```

### Environment Variables

- `UNIWEATHER_TOKEN`: API authentication token
- `UNIWEATHER_URL`: API base URL

## API Reference

### uniWeatherCloud

Main async client for the uniWeather API.

**Methods:**

- `connect(token: str)` - Authenticate with API token
- `my_devices(all: bool = False)` - Get accessible devices (default: only assigned/handled devices; `all=True`: include unhandled devices)
- `get_channels(device)` - Get available channels for a device
- `data(device, channels=None, from_date=None, to_date=None, format="dataframe")` - Query device data
- `download_csv(device, filename, channels=None, from_date=None, to_date=None)` - Download data as CSV
- `close()` - Close connection

### uniWeatherCloudSync

Synchronous wrapper with the same methods (without `await`).

## Error Handling

```python
from uniWeather import (
    UniWeatherError,
    AuthenticationError,
    NotFoundError,
    APIError
)

try:
    await client.connect(token="invalid")
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except APIError as e:
    print(f"API error: {e}")
```

## Configuration

### Custom Base URL

For local development:

```python
client = uniWeatherCloud(base_url="http://localhost:8080")
```

## Support

- Email: support@uniweather.io
- Documentation: https://docs.uniweather.io

## License

MIT License
