Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version: "3.12"

- name: Set up uv
uses: astral-sh/setup-uv@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
python-version: "3.12"

- name: Retrieve version from tag name
id: retrieve-version
Expand Down
22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,10 @@ pip install pyoverkiz

```python
import asyncio
import time

from pyoverkiz.auth.credentials import UsernamePasswordCredentials
from pyoverkiz.client import OverkizClient
from pyoverkiz.models import Action
from pyoverkiz.models import Action, Command
from pyoverkiz.enums import Server, OverkizCommand

USERNAME = ""
Expand All @@ -51,16 +50,12 @@ async def main() -> None:
server=Server.SOMFY_EUROPE,
credentials=UsernamePasswordCredentials(USERNAME, PASSWORD),
) as client:
try:
await client.login()
except Exception as exception: # pylint: disable=broad-except
print(exception)
return
await client.login()

devices = await client.get_devices()

for device in devices:
print(f"{device.label} ({device.id}) - {device.controllable_name}")
print(f"{device.label} ({device.device_url}) - {device.controllable_name}")
print(f"{device.widget} - {device.ui_class}")

await client.execute_action_group(
Expand All @@ -80,7 +75,7 @@ async def main() -> None:
events = await client.fetch_events()
print(events)

time.sleep(2)
await asyncio.sleep(2)


asyncio.run(main())
Expand All @@ -90,7 +85,6 @@ asyncio.run(main())

```python
import asyncio
import time

from pyoverkiz.auth.credentials import LocalTokenCredentials
from pyoverkiz.client import OverkizClient
Expand All @@ -110,7 +104,7 @@ async def main() -> None:
) as client:
await client.login()

print("Local API connection succesfull!")
print("Local API connection successful!")

print(await client.get_api_version())

Expand All @@ -121,14 +115,14 @@ async def main() -> None:
print(devices)

for device in devices:
print(f"{device.label} ({device.id}) - {device.controllable_name}")
print(f"{device.label} ({device.device_url}) - {device.controllable_name}")
print(f"{device.widget} - {device.ui_class}")

while True:
events = await client.fetch_events()
print(events)

time.sleep(2)
await asyncio.sleep(2)


asyncio.run(main())
Expand Down Expand Up @@ -157,7 +151,7 @@ If you use Visual Studio Code with Docker or GitHub Codespaces, you can take adv

- Install [uv](https://docs.astral.sh/uv/getting-started/installation).
- Clone this repository and navigate to it: `cd python-overkiz-api`
- Initialize the project with `uv sync`, then run `uv run pre-commit install`
- Initialize the project with `uv sync`, then run `uv run prek install`

#### Tests

Expand Down
2 changes: 1 addition & 1 deletion docs/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ uv run pytest

## Project guidelines

- Use Python 3.10+ features and type annotations.
- Use Python 3.12+ features and type annotations.
- Keep absolute imports and avoid relative imports.
- Preserve existing comments and logging unless your change requires updates.
- Prefer small, focused changes and add tests when behavior changes.
Expand Down
3 changes: 2 additions & 1 deletion docs/device-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ await client.execute_action_group(
- Use a single action group to batch multiple device commands.

```python
from pyoverkiz.enums import OverkizCommand
from pyoverkiz.enums import OverkizCommand, OverkizCommandParam
from pyoverkiz.models import Action, Command

await client.execute_action_group(
Expand All @@ -195,6 +195,7 @@ await client.execute_action_group(
],
label="Execution: multiple commands",
)
```

## Limitations and rate limits

Expand Down
56 changes: 0 additions & 56 deletions docs/error-handling.md

This file was deleted.

32 changes: 0 additions & 32 deletions docs/event-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,38 +59,6 @@ async def main() -> None:
await asyncio.sleep(2)


asyncio.run(main())
```

## Update an in-memory state map

```python
import asyncio

from pyoverkiz.auth.credentials import UsernamePasswordCredentials
from pyoverkiz.client import OverkizClient
from pyoverkiz.enums import Server


async def main() -> None:
async with OverkizClient(
server=Server.SOMFY_EUROPE,
credentials=UsernamePasswordCredentials("you@example.com", "password"),
) as client:
await client.login()
await client.register_event_listener()

state_map: dict[str, dict[str, object]] = {}

while True:
events = await client.fetch_events()
for event in events:
device_id = event.device_id
state_map.setdefault(device_id, {})[event.state_name] = event.state_value

await asyncio.sleep(2)


asyncio.run(main())
```

Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This guide will help you install the library, connect to your hub, and perform y

## Prerequisites

- Python 3.10+
- Python 3.12+
- An OverKiz-compatible hub and account

## Install pyOverkiz from PyPI
Expand Down Expand Up @@ -97,7 +97,7 @@ Use a cloud server when you want to connect through the vendor’s public API. U

async def main() -> None:
async with OverkizClient(
server=Server.SOMFY_EUROPE,
server=Server.ATLANTIC_COZYTOUCH,
credentials=UsernamePasswordCredentials("you@example.com", "password"),
) as client:
await client.login()
Expand Down
6 changes: 4 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ pyOverkiz is an async Python library for interacting with Overkiz-based platform
- Somfy TaHoma
- Somfy TaHoma Switch
- Thermor Cozytouch
<!-- - Brandt Smart Control **\*** -->
<!-- - Rexel Energeasy Connect **\*** -->
- Brandt Smart Control **\***
- Rexel Energeasy Connect **\***

\[*] _These servers utilize an authentication method that is currently not supported by this library._
Comment thread
iMicknl marked this conversation as resolved.
68 changes: 57 additions & 11 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,65 @@
# Troubleshooting

## Cloud vs local connectivity

- Cloud servers require internet access and valid vendor credentials.
- Local servers require direct access to the gateway on your LAN.

## SSL and .local hostnames

If the gateway uses a self-signed certificate, pass `verify_ssl=False` when creating `OverkizClient` for local access.

## Authentication failures

- Confirm the server matches your vendor region.
- Confirm the server matches your vendor and region.
- Re-run `login()` and retry the call.
- On `NotAuthenticatedError`, re-authenticate before retrying.

## Rate limits and concurrency

- Reduce polling frequency.
- Back off on `TooManyRequestsError` or `TooManyConcurrentRequestsError`.
- Use short, jittered delays for transient errors.

```python
import asyncio

from pyoverkiz.auth.credentials import UsernamePasswordCredentials
from pyoverkiz.client import OverkizClient
from pyoverkiz.enums import Server
from pyoverkiz.exceptions import (
NotAuthenticatedError,
TooManyConcurrentRequestsError,
TooManyRequestsError,
)


async def fetch_devices_with_retry() -> None:
async with OverkizClient(
server=Server.SOMFY_EUROPE,
credentials=UsernamePasswordCredentials("you@example.com", "password"),
) as client:
await client.login()
for attempt in range(5):
try:
devices = await client.get_devices()
print(devices)
return
except (TooManyRequestsError, TooManyConcurrentRequestsError):
await asyncio.sleep(0.5 * (attempt + 1))
Comment thread
iMicknl marked this conversation as resolved.
except NotAuthenticatedError:
await client.login()


asyncio.run(fetch_devices_with_retry())
```

## Common errors

- `NotAuthenticatedError`
- `BadCredentialsError`
- `TooManyRequestsError`
- `TooManyConcurrentRequestsError`
- `TooManyExecutionsError`
- `MaintenanceError`
- `AccessDeniedToGatewayError`

## SSL and local certificates

- Cloud servers require internet access and valid vendor credentials.
- Local servers require direct access to the gateway on your LAN.
- If the gateway uses a self-signed certificate, pass `verify_ssl=False` when creating `OverkizClient` for local access.

## Listener drops

Expand All @@ -29,7 +71,11 @@ If the gateway uses a self-signed certificate, pass `verify_ssl=False` when crea
- Refresh setup with `get_setup()` and re-fetch devices.
- Confirm you are using the correct gateway and server.

## Logging tips
## Timeouts

For long-running operations, prefer shorter request timeouts with retries rather than a single long timeout.

## Logging

Enable debug logging in your application to inspect request/response details.

Expand Down
1 change: 0 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ nav:
- Device control: device-control.md
- Action queue: action-queue.md
- Event handling: event-handling.md
- Error handling: error-handling.md
- Troubleshooting: troubleshooting.md
- API Reference: api-reference.md
- Contribute: contribute.md
Loading