Skip to content
Draft

2.0 #1872

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
50809f7
Bump minimum required Python version to 3.12 (#1871)
iMicknl Dec 29, 2025
ef41dc7
Bump version to 2.0
iMicknl Dec 29, 2025
7e041d1
Rename Scenario to ActionGroup (and relevant methods), reuse ActionGr…
iMicknl Dec 29, 2025
7061b7d
Add `execute_action_group` method and remove other command execution …
iMicknl Dec 29, 2025
f8c7ca3
Refactor authentication handling in OverkizClient and add new credent…
iMicknl Jan 3, 2026
41bb7ad
Migrate pre-commit to prek (rust based) (#1887)
iMicknl Jan 9, 2026
96c71f7
Improve developer documentation (#1908)
iMicknl Jan 24, 2026
a24c462
Fix uv.lock after rebase
iMicknl Jan 25, 2026
e53071a
Update test files to clarify ruff noqa comments and improve readabili…
iMicknl Jan 25, 2026
75674ec
Implement ActionQueue for batching actions in OverkizClient (#1866)
iMicknl Jan 25, 2026
af84861
Redact
iMicknl Jan 26, 2026
0b7d087
Update API Docs mirror to the latest version (#1924)
iMicknl Jan 29, 2026
7de3c3d
Fix JSON syntax in tasks.json by adding missing comma and problemMatcher
iMicknl Jan 29, 2026
e0a8a80
Improve Device model (#1930)
iMicknl Jan 31, 2026
e50b86d
Update uv lock
iMicknl Jan 31, 2026
0b8a6a3
Improve Device helpers (#1932)
iMicknl Jan 31, 2026
30a2fb2
Improve enum structure (#1925)
iMicknl Feb 21, 2026
8c9d3fc
Add server choice to enum generation scripts and improve CozyTouch en…
iMicknl Apr 5, 2026
8eb08cf
Apply feedback to v2 branch (#1971)
iMicknl Apr 5, 2026
3b714ee
Refactor and implement feedback on v2 (#1973)
iMicknl Apr 6, 2026
137563c
Fix Python model for Local API (id = None) (#1974)
iMicknl Apr 6, 2026
bf3b321
Add an option to disable PII masking in get_diagnostic_data (enabled …
iMicknl Apr 6, 2026
8a09223
Simplify return statements and rename `type` parameter to `api_type` …
iMicknl Apr 6, 2026
d3fa87a
Simplify error handling and move response checks to a response_handle…
iMicknl Apr 7, 2026
abbc876
Rename all exceptions from *Exception to *Error (N818) (#1987)
iMicknl Apr 17, 2026
0cbf97d
Replace pyhumps dependency with internal _case module (#1988)
iMicknl Apr 17, 2026
0f295c2
Remove description of pyhumps dependency from _case.py docstring
iMicknl Apr 17, 2026
3c520ad
Refactor API request methods to streamline response handling and redu…
iMicknl Apr 17, 2026
917bfef
Lazy-import boto3 in NexityAuthStrategy (#1990)
iMicknl Apr 17, 2026
3b6d6ce
Rename ServerConfig.type to api_type (#1995)
iMicknl Apr 17, 2026
3968d7b
Increase cache size for _decamelize_key function to improve performance
iMicknl Apr 19, 2026
89c3363
Fix token expiration calculation by removing skew adjustment
iMicknl Apr 19, 2026
2f8e167
Normalize error message formatting for consistent substring matching …
iMicknl Apr 19, 2026
a15bac9
Remove api_type parameter from authentication strategy constructors
iMicknl Apr 19, 2026
ed1eb8f
Improve documentation (v2) (#1996)
iMicknl Apr 19, 2026
825b6b7
Rename CommandMode, cancel_command, and scenario methods (#1997)
iMicknl Apr 19, 2026
3c03719
Enable ruff PT rules (pytest style) (#2000)
iMicknl Apr 19, 2026
efa3be4
Enable additional ruff lint rules (zero-violation batch) (#1998)
iMicknl Apr 19, 2026
764581f
Enable ruff FURB, PERF, RSE, RET, PIE rules (#2001)
iMicknl Apr 19, 2026
4650dbd
Enable ruff ERA rule and fix commented-out code
iMicknl Apr 19, 2026
50e1ff5
Enable ruff PYI rule (type annotation improvements) (#2003)
iMicknl Apr 19, 2026
a35befd
Enable ruff PTH rule (migrate to pathlib) (#2004)
iMicknl Apr 19, 2026
6511168
Enable ruff A rule (builtin shadowing detection) (#2005)
iMicknl Apr 19, 2026
5ecc668
Enable ruff PL (pylint) rules
iMicknl Apr 19, 2026
b034971
Replace magic HTTP status codes with HTTPStatus constants
iMicknl Apr 19, 2026
9f4acfa
Improve error handling and add comprehensive client tests (#2007)
iMicknl Apr 19, 2026
ef66c7a
Add firmware management methods and UnsupportedOperationError exception
iMicknl Apr 19, 2026
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
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "uv sync && uv run pre-commit install",
"postCreateCommand": "uv sync --all-extras --dev && uv run prek install",
// Configure tool-specific properties.
"customizations": {
"vscode": {
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: docs

on:
release:
types:
- created
pull_request:
paths:
- docs/**
- mkdocs.yml
- pyproject.toml
- README.md

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

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

- name: Set up uv
uses: astral-sh/setup-uv@v3

- name: Install docs dependencies
run: uv sync --all-extras --dev

- name: Build site
run: uv run mkdocs build

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: site

deploy:
if: github.event_name == 'release'
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
6 changes: 3 additions & 3 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v6
Expand All @@ -32,7 +32,7 @@ jobs:
- name: Install the project
run: uv sync --all-extras --dev

- name: Run pre-commit
- name: Run prek (pre-commit checks)
env:
SKIP: ${{ github.ref == 'refs/heads/main' && 'no-commit-to-branch' || '' }}
run: uv run pre-commit run --show-diff-on-failure --color=always --all-files
run: uv run prek run --show-diff-on-failure --color=always --all-files
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v6
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ repos:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
exclude: .devcontainer
exclude: .devcontainer|.vscode
- id: check-yaml
- id: check-added-large-files
- id: no-commit-to-branch
Expand Down
18 changes: 18 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Docs: Serve (development)",
"type": "shell",
"command": "uv run mkdocs serve",
"problemMatcher": []
},
{
"label": "Docs: Build",
"type": "shell",
"command": "uv run mkdocs build --clean"
}
]
}
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ Always use full type annotations, generics, and other modern practices.
# Install all dependencies:
uv sync

# Run linting (with ruff), pre-commit checks and type checking (with mypy).
# Run linting (with ruff), prek (pre-commit alternative) checks and type checking (with mypy).
# Note when you run this, ruff will auto-format and sort imports, resolving any
# linter warnings about import ordering:
uv run pre-commit run --all-files
uv run prek run --all-files

# Run tests:
uv run pytest
Expand Down
65 changes: 29 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,37 +35,47 @@ pip install pyoverkiz

```python
import asyncio
import time

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

USERNAME = ""
PASSWORD = ""


async def main() -> None:
async with OverkizClient(
USERNAME, PASSWORD, server=SUPPORTED_SERVERS[Server.SOMFY_EUROPE]
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(
actions=[
Action(
device_url="io://1234-5678-1234/12345678",
commands=[
Command(name=OverkizCommand.SET_CLOSURE, parameters=[100])
]
)
],
label="Execution via Python",
# mode=ExecutionMode.HIGH_PRIORITY
)

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

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


asyncio.run(main())
Expand All @@ -75,43 +85,26 @@ asyncio.run(main())

```python
import asyncio
import time
import aiohttp

from pyoverkiz.auth.credentials import LocalTokenCredentials
from pyoverkiz.client import OverkizClient
from pyoverkiz.const import SUPPORTED_SERVERS, OverkizServer
from pyoverkiz.enums import Server
from pyoverkiz.utils import create_local_server_config

USERNAME = ""
PASSWORD = ""
LOCAL_GATEWAY = "gateway-xxxx-xxxx-xxxx.local" # or use the IP address of your gateway
VERIFY_SSL = True # set verify_ssl to False if you don't use the .local hostname


async def main() -> None:
token = "" # generate your token via the Somfy app and include it here

# Local Connection
session = aiohttp.ClientSession(
connector=aiohttp.TCPConnector(verify_ssl=VERIFY_SSL)
)

async with OverkizClient(
username="",
password="",
token=token,
session=session,
server=create_local_server_config(host=LOCAL_GATEWAY),
credentials=LocalTokenCredentials(token),
verify_ssl=VERIFY_SSL,
server=OverkizServer(
name="Somfy TaHoma (local)",
endpoint=f"https://{LOCAL_GATEWAY}:8443/enduser-mobile-web/1/enduserAPI/",
manufacturer="Somfy",
configuration_url=None,
),
) as client:
await client.login()

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

print(await client.get_api_version())

Expand All @@ -122,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 @@ -158,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
Loading