# Kerblwelt API Client
Python API client for [Kerbl Welt IoT platform](https://app.kerbl-iot.com), which powers the AKO Smart Satellite electric fence monitoring system.
## Features
- **Async/await** support for efficient I/O operations
- **Full type hints** for better IDE support and type checking
- **Automatic token management** with refresh capability
- **Comprehensive error handling** with custom exceptions
- **Data models** using Python dataclasses
- **Well-tested** with pytest
## Installation
```bash
pip install kerblwelt-api
```
Or for development:
```bash
git clone https://github.com/stgarrity/kerblwelt-api
cd kerblwelt-api
pip install -e ".[dev]"
```
## Quick Start
```python
import asyncio
from kerblwelt_api import KerblweltClient
async def main():
async with KerblweltClient() as client:
# Authenticate
await client.authenticate("your-email@example.com", "your-password")
# Get all devices
devices = await client.get_devices()
for device in devices:
print(f"Device: {device.description}")
print(f" Fence Voltage: {device.fence_voltage}V")
print(f" Battery: {device.battery_state}%")
print(f" Signal: {device.signal_quality}%")
print(f" Online: {device.is_online}")
print(f" Status: {'OK' if device.is_fence_voltage_ok else 'LOW VOLTAGE!'}")
if __name__ == "__main__":
asyncio.run(main())
```
## Usage
### Authentication
```python
async with KerblweltClient() as client:
# Method 1: Authenticate with credentials
await client.authenticate("email@example.com", "password")
# Method 2: Restore previous session with tokens
client.set_tokens(
access_token="eyJhbGci...",
refresh_token="eyJhbGci..."
)
```
### Get User Information
```python
user = await client.get_user()
print(f"User: {user.email}")
print(f"Timezone: {user.timezone}")
print(f"Language: {user.language}")
```
### Get Devices
```python
# Get all Smart Satellite devices
devices = await client.get_devices()
# Get a specific device by ID
device = await client.get_device("device-uuid-here")
# Get device with event count
device_data = await client.get_all_device_data()
for device_id, (device, events) in device_data.items():
print(f"{device.description}: {events.new} new events")
```
### Access Device Properties
```python
device = devices[0]
# Basic info
print(device.description) # User-defined name
print(device.id) # Device UUID
print(device.identifier) # Serial number
# Status
print(device.is_online) # Online/offline
print(device.is_fence_voltage_ok) # Voltage above threshold
print(device.is_battery_low) # Battery below 20%
# Measurements
print(device.fence_voltage) # Current voltage (V)
print(device.battery_voltage) # Battery voltage (V)
print(device.battery_state) # Battery percentage (0-100)
print(device.signal_quality) # Signal strength (0-100)
# Thresholds
print(device.fence_voltage_alarm_threshold) # Alert threshold (V)
# Timestamps
print(device.registered_at) # Registration date
print(device.first_online_at) # First connection
print(device.offline_since) # Last offline time
```
### Token Refresh
The client automatically handles token expiration. You can also manually refresh:
```python
try:
devices = await client.get_devices()
except TokenExpiredError:
await client.refresh_token()
devices = await client.get_devices()
```
### Error Handling
```python
from kerblwelt_api import (
InvalidCredentialsError,
DeviceNotFoundError,
APIError,
ConnectionError,
)
try:
await client.authenticate("email@example.com", "wrong-password")
except InvalidCredentialsError:
print("Invalid email or password")
except ConnectionError:
print("Cannot connect to Kerbl Welt API")
except APIError as e:
print(f"API error: {e}")
```
## API Reference
### KerblweltClient
Main client class for interacting with Kerbl Welt API.
**Methods:**
- `authenticate(email: str, password: str) -> None` - Authenticate with credentials
- `set_tokens(access_token: str, refresh_token: str) -> None` - Set tokens manually
- `refresh_token() -> None` - Refresh the access token
- `get_user() -> User` - Get current user information
- `get_devices() -> list[SmartSatelliteDevice]` - Get all Smart Satellite devices
- `get_device(device_id: str) -> SmartSatelliteDevice` - Get specific device
- `get_device_event_count(device_id: str) -> DeviceEventCount` - Get event count
- `get_all_device_data() -> dict` - Get all devices with event counts
- `close() -> None` - Close the client session
**Properties:**
- `is_authenticated: bool` - Check if client is authenticated
### SmartSatelliteDevice
Represents an AKO Smart Satellite electric fence monitor.
**Key Attributes:**
- `id: str` - Device UUID
- `description: str` - User-defined device name
- `fence_voltage: int` - Current fence voltage in volts
- `battery_voltage: float` - Battery voltage in volts
- `battery_state: int` - Battery percentage (0-100)
- `signal_quality: int` - Signal strength (0-100)
- `is_online: bool` - Device online status
- `fence_voltage_alarm_threshold: int` - Alert threshold in volts
**Helper Properties:**
- `is_fence_voltage_ok: bool` - Voltage above threshold
- `is_battery_low: bool` - Battery below 20%
### Exceptions
All exceptions inherit from `KerblweltError`:
- `AuthenticationError` - Base authentication error
- `InvalidCredentialsError` - Wrong email/password
- `TokenExpiredError` - Token has expired
- `TokenRefreshError` - Token refresh failed
- `APIError` - API request failed
- `ConnectionError` - Network connection failed
- `DeviceNotFoundError` - Device ID not found
- `RateLimitError` - API rate limit exceeded
- `ValidationError` - Input validation failed
## Development
### Setup
```bash
# Clone repository
git clone https://github.com/stgarrity/kerblwelt-api
cd kerblwelt-api
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install with dev dependencies
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=kerblwelt_api
# Run specific test file
pytest tests/test_client.py
```
### Code Quality
```bash
# Format code
black kerblwelt_api tests
# Lint code
ruff check kerblwelt_api tests
# Type checking
mypy kerblwelt_api
```
## Requirements
- Python 3.11 or higher
- aiohttp 3.9.0 or higher
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## Acknowledgments
- Built for the [Kerbl Welt IoT platform](https://app.kerbl-iot.com)
- Powers AKO Smart Satellite electric fence monitors
- Designed for integration with Home Assistant
## Links
- [Kerbl Welt Web App](https://app.kerbl-iot.com)
- [AKO Smart Satellite Product Info](https://www.kerbl.com/en/product/ako-smart-satellite/)
- [Home Assistant Integration](https://github.com/stgarrity/homeassistant-kerblwelt)
## Support
For issues and questions:
- [GitHub Issues](https://github.com/stgarrity/kerblwelt-api/issues)
- Email: sgarrity@gmail.com
Raw data
{
"_id": null,
"home_page": null,
"name": "kerblwelt-api",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "kerbl, ako, smart-satellite, electric-fence, iot, api-client",
"author": null,
"author_email": "Steve Garrity <sgarrity@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/f5/1c/ba4f86ff86898dcbd0969ac668ba2a422227982cb76fd8d0b547ab9984d9/kerblwelt_api-0.1.0.tar.gz",
"platform": null,
"description": "# Kerblwelt API Client\n\nPython API client for [Kerbl Welt IoT platform](https://app.kerbl-iot.com), which powers the AKO Smart Satellite electric fence monitoring system.\n\n## Features\n\n- **Async/await** support for efficient I/O operations\n- **Full type hints** for better IDE support and type checking\n- **Automatic token management** with refresh capability\n- **Comprehensive error handling** with custom exceptions\n- **Data models** using Python dataclasses\n- **Well-tested** with pytest\n\n## Installation\n\n```bash\npip install kerblwelt-api\n```\n\nOr for development:\n\n```bash\ngit clone https://github.com/stgarrity/kerblwelt-api\ncd kerblwelt-api\npip install -e \".[dev]\"\n```\n\n## Quick Start\n\n```python\nimport asyncio\nfrom kerblwelt_api import KerblweltClient\n\nasync def main():\n async with KerblweltClient() as client:\n # Authenticate\n await client.authenticate(\"your-email@example.com\", \"your-password\")\n\n # Get all devices\n devices = await client.get_devices()\n\n for device in devices:\n print(f\"Device: {device.description}\")\n print(f\" Fence Voltage: {device.fence_voltage}V\")\n print(f\" Battery: {device.battery_state}%\")\n print(f\" Signal: {device.signal_quality}%\")\n print(f\" Online: {device.is_online}\")\n print(f\" Status: {'OK' if device.is_fence_voltage_ok else 'LOW VOLTAGE!'}\")\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n## Usage\n\n### Authentication\n\n```python\nasync with KerblweltClient() as client:\n # Method 1: Authenticate with credentials\n await client.authenticate(\"email@example.com\", \"password\")\n\n # Method 2: Restore previous session with tokens\n client.set_tokens(\n access_token=\"eyJhbGci...\",\n refresh_token=\"eyJhbGci...\"\n )\n```\n\n### Get User Information\n\n```python\nuser = await client.get_user()\nprint(f\"User: {user.email}\")\nprint(f\"Timezone: {user.timezone}\")\nprint(f\"Language: {user.language}\")\n```\n\n### Get Devices\n\n```python\n# Get all Smart Satellite devices\ndevices = await client.get_devices()\n\n# Get a specific device by ID\ndevice = await client.get_device(\"device-uuid-here\")\n\n# Get device with event count\ndevice_data = await client.get_all_device_data()\nfor device_id, (device, events) in device_data.items():\n print(f\"{device.description}: {events.new} new events\")\n```\n\n### Access Device Properties\n\n```python\ndevice = devices[0]\n\n# Basic info\nprint(device.description) # User-defined name\nprint(device.id) # Device UUID\nprint(device.identifier) # Serial number\n\n# Status\nprint(device.is_online) # Online/offline\nprint(device.is_fence_voltage_ok) # Voltage above threshold\nprint(device.is_battery_low) # Battery below 20%\n\n# Measurements\nprint(device.fence_voltage) # Current voltage (V)\nprint(device.battery_voltage) # Battery voltage (V)\nprint(device.battery_state) # Battery percentage (0-100)\nprint(device.signal_quality) # Signal strength (0-100)\n\n# Thresholds\nprint(device.fence_voltage_alarm_threshold) # Alert threshold (V)\n\n# Timestamps\nprint(device.registered_at) # Registration date\nprint(device.first_online_at) # First connection\nprint(device.offline_since) # Last offline time\n```\n\n### Token Refresh\n\nThe client automatically handles token expiration. You can also manually refresh:\n\n```python\ntry:\n devices = await client.get_devices()\nexcept TokenExpiredError:\n await client.refresh_token()\n devices = await client.get_devices()\n```\n\n### Error Handling\n\n```python\nfrom kerblwelt_api import (\n InvalidCredentialsError,\n DeviceNotFoundError,\n APIError,\n ConnectionError,\n)\n\ntry:\n await client.authenticate(\"email@example.com\", \"wrong-password\")\nexcept InvalidCredentialsError:\n print(\"Invalid email or password\")\nexcept ConnectionError:\n print(\"Cannot connect to Kerbl Welt API\")\nexcept APIError as e:\n print(f\"API error: {e}\")\n```\n\n## API Reference\n\n### KerblweltClient\n\nMain client class for interacting with Kerbl Welt API.\n\n**Methods:**\n\n- `authenticate(email: str, password: str) -> None` - Authenticate with credentials\n- `set_tokens(access_token: str, refresh_token: str) -> None` - Set tokens manually\n- `refresh_token() -> None` - Refresh the access token\n- `get_user() -> User` - Get current user information\n- `get_devices() -> list[SmartSatelliteDevice]` - Get all Smart Satellite devices\n- `get_device(device_id: str) -> SmartSatelliteDevice` - Get specific device\n- `get_device_event_count(device_id: str) -> DeviceEventCount` - Get event count\n- `get_all_device_data() -> dict` - Get all devices with event counts\n- `close() -> None` - Close the client session\n\n**Properties:**\n\n- `is_authenticated: bool` - Check if client is authenticated\n\n### SmartSatelliteDevice\n\nRepresents an AKO Smart Satellite electric fence monitor.\n\n**Key Attributes:**\n\n- `id: str` - Device UUID\n- `description: str` - User-defined device name\n- `fence_voltage: int` - Current fence voltage in volts\n- `battery_voltage: float` - Battery voltage in volts\n- `battery_state: int` - Battery percentage (0-100)\n- `signal_quality: int` - Signal strength (0-100)\n- `is_online: bool` - Device online status\n- `fence_voltage_alarm_threshold: int` - Alert threshold in volts\n\n**Helper Properties:**\n\n- `is_fence_voltage_ok: bool` - Voltage above threshold\n- `is_battery_low: bool` - Battery below 20%\n\n### Exceptions\n\nAll exceptions inherit from `KerblweltError`:\n\n- `AuthenticationError` - Base authentication error\n - `InvalidCredentialsError` - Wrong email/password\n - `TokenExpiredError` - Token has expired\n - `TokenRefreshError` - Token refresh failed\n- `APIError` - API request failed\n- `ConnectionError` - Network connection failed\n- `DeviceNotFoundError` - Device ID not found\n- `RateLimitError` - API rate limit exceeded\n- `ValidationError` - Input validation failed\n\n## Development\n\n### Setup\n\n```bash\n# Clone repository\ngit clone https://github.com/stgarrity/kerblwelt-api\ncd kerblwelt-api\n\n# Create virtual environment\npython3 -m venv venv\nsource venv/bin/activate\n\n# Install with dev dependencies\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=kerblwelt_api\n\n# Run specific test file\npytest tests/test_client.py\n```\n\n### Code Quality\n\n```bash\n# Format code\nblack kerblwelt_api tests\n\n# Lint code\nruff check kerblwelt_api tests\n\n# Type checking\nmypy kerblwelt_api\n```\n\n## Requirements\n\n- Python 3.11 or higher\n- aiohttp 3.9.0 or higher\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## Acknowledgments\n\n- Built for the [Kerbl Welt IoT platform](https://app.kerbl-iot.com)\n- Powers AKO Smart Satellite electric fence monitors\n- Designed for integration with Home Assistant\n\n## Links\n\n- [Kerbl Welt Web App](https://app.kerbl-iot.com)\n- [AKO Smart Satellite Product Info](https://www.kerbl.com/en/product/ako-smart-satellite/)\n- [Home Assistant Integration](https://github.com/stgarrity/homeassistant-kerblwelt)\n\n## Support\n\nFor issues and questions:\n- [GitHub Issues](https://github.com/stgarrity/kerblwelt-api/issues)\n- Email: sgarrity@gmail.com\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python API client for Kerbl Welt IoT platform (AKO Smart Satellite electric fence monitors)",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/stgarrity/kerblwelt-api",
"Issues": "https://github.com/stgarrity/kerblwelt-api/issues",
"Repository": "https://github.com/stgarrity/kerblwelt-api"
},
"split_keywords": [
"kerbl",
" ako",
" smart-satellite",
" electric-fence",
" iot",
" api-client"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "660d40e780d3fae433447c314b5435188b0083dccf4cd4e48df66bf97a5bd792",
"md5": "c85126383c66778328b2d7e92bc219de",
"sha256": "75b7fd398d294bbd4967bcc2555a3a648edf66bab3d0eac35b2ab2db2cb7fe45"
},
"downloads": -1,
"filename": "kerblwelt_api-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c85126383c66778328b2d7e92bc219de",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 13065,
"upload_time": "2025-10-21T03:45:34",
"upload_time_iso_8601": "2025-10-21T03:45:34.473177Z",
"url": "https://files.pythonhosted.org/packages/66/0d/40e780d3fae433447c314b5435188b0083dccf4cd4e48df66bf97a5bd792/kerblwelt_api-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f51cba4f86ff86898dcbd0969ac668ba2a422227982cb76fd8d0b547ab9984d9",
"md5": "82ff1e5fcf11029f28804a2fe459a518",
"sha256": "376ffa168defc077d932756c99683daf9dbf3e3888ff0cc3a92b6fb071698d7a"
},
"downloads": -1,
"filename": "kerblwelt_api-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "82ff1e5fcf11029f28804a2fe459a518",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 13835,
"upload_time": "2025-10-21T03:45:35",
"upload_time_iso_8601": "2025-10-21T03:45:35.614100Z",
"url": "https://files.pythonhosted.org/packages/f5/1c/ba4f86ff86898dcbd0969ac668ba2a422227982cb76fd8d0b547ab9984d9/kerblwelt_api-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-21 03:45:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stgarrity",
"github_project": "kerblwelt-api",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "kerblwelt-api"
}