Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Refactor to have "objects" inherit from "object_interfaces" #162

Merged
merged 40 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
53adee5
Move object_interfaces to top level module
loopj Dec 18, 2024
b12d01d
XML fields are PascalCase by convention, rename model fields to match…
loopj Dec 18, 2024
34f5a99
Encapsulate model sub-types under model classes
loopj Dec 18, 2024
ded44e5
Rename models module to objects, move it to top level
loopj Dec 18, 2024
aeaac34
Import MTime as python datetime object
loopj Dec 18, 2024
79f6792
Shove all objects into a single file
loopj Dec 18, 2024
fc066ce
Make objects implement interfaces directly
loopj Dec 18, 2024
a38a330
Address ruff config deprecations
loopj Dec 18, 2024
cd6c909
Add note about 2.x firmware
loopj Dec 18, 2024
4087193
Back to module per class for objects
loopj Dec 18, 2024
d6e4af4
Add support for datetime parsing
loopj Dec 18, 2024
437ffda
Fix vid->obj lookup bug
loopj Dec 18, 2024
5e5ed25
Rename back boxes controller
loopj Dec 18, 2024
76d4bac
Use types instead of strings for vantage_types for type safety
loopj Dec 18, 2024
474ce12
Allow passing vid to invoke
loopj Dec 19, 2024
92436dc
Remove object_interface related stuff from command_client README
loopj Dec 19, 2024
db053b0
Revert vid change
loopj Dec 19, 2024
3c19c2d
Fix typing for load level
loopj Dec 19, 2024
3983fc5
Improve 'control_load' example
loopj Dec 19, 2024
0ec8834
Helper function to get all interfaces an object supports
loopj Dec 19, 2024
833aa8e
Minor readme update
loopj Dec 19, 2024
e3b4038
Precisely define enum types in interfaces
loopj Dec 19, 2024
3f2522a
kw_only all object dataclasses, add some more common fields
loopj Dec 21, 2024
1aa99ea
Try local mypy
loopj Dec 21, 2024
ec8b024
Specify target python version
loopj Dec 21, 2024
985220c
Drop hatch in favor of uv and bumpver
loopj Dec 21, 2024
04dba4a
Adjust approach to loading all SystemObject classes into memory
loopj Dec 21, 2024
662360e
Switch to pyright, use github actions over precommit
loopj Dec 21, 2024
272e748
Add uv venv to path
loopj Dec 21, 2024
3e393c5
Use ruff for formatting
loopj Dec 22, 2024
1f7cde0
Python version test matrix
loopj Dec 22, 2024
8e28ef4
Add home automation classifier
loopj Dec 22, 2024
d24e3ca
Explicitly specify pyright checking mode
loopj Dec 22, 2024
d458b64
Various minor changes based on lint recommendations
loopj Dec 22, 2024
9218321
Add recommended extensions
loopj Dec 23, 2024
7dc4846
Full drop precommit
loopj Dec 23, 2024
02055bb
Strict predicate typing on queryset filters
loopj Dec 23, 2024
08a9629
Minor typing changes
loopj Dec 23, 2024
293ca6e
Remove ignore from ruff lint
loopj Dec 23, 2024
318a336
Recommend pylance instead
loopj Dec 23, 2024
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
44 changes: 44 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: pre-commit

on:
pull_request:
push:
branches: [main]

jobs:
pre-commit:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
python-version: ${{ matrix.python-version }}

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

- name: Add venv to PATH
run: echo "$PWD/.venv/bin" >> $GITHUB_PATH

- name: Run ruff linter
uses: astral-sh/ruff-action@v2
with:
args: check

- name: Run ruff formatter
uses: astral-sh/ruff-action@v2
with:
args: format --check

- name: Run pyright
uses: jakebailey/pyright-action@v2
16 changes: 0 additions & 16 deletions .github/workflows/pre-commit.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ __pycache__/
*.so
*~
.idea
uv.lock
25 changes: 0 additions & 25 deletions .pre-commit-config.yaml

This file was deleted.

92 changes: 0 additions & 92 deletions .pylintrc

This file was deleted.

6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"ms-python.vscode-pylance",
"charliermarsh.ruff"
]
}
70 changes: 35 additions & 35 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,30 @@ First off, thanks for taking the time to contribute!

## 🔨 Set up Development Environment

### Using `hatch`
### Using `uv`

aiovantage uses [Hatch](https://hatch.pypa.io/) to run scripts, manages virtual environments, create reproducible builds, and publish packages. Check out the [Hatch installation guide](https://hatch.pypa.io/latest/install/) to get started.
aiovantage uses [uv](https://docs.astral.sh/uv/) to run scripts, manages virtual environments, create reproducible builds, and publish packages. Check out the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/) to get started.

If you'd like to run a command in a virtual environment with development dependencies available, prefix it with `hatch -e dev run`. For example,
To set up your development environment, run the following commands:

```bash
hatch -e dev run python examples/dump_system.py hostname
uv venv
uv pip install -e ".[dev]"
```

If you'd like to run a command in a virtual environment with development dependencies available, prefix it with `uv run`. For example,

```bash
uv run python examples/dump_system.py hostname
```

### Manually

If you'd prefer to manage your own python environment, you can install the development dependencies manually.

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

Expand All @@ -42,12 +51,12 @@ pip install -e ".[dev]"

To add a new object type to an existing controller, follow these steps:

- Create a new [xsdata-style `@dataclass`](https://xsdata.readthedocs.io/en/latest/models.html) model in `src/aiovantage/config_client/models/`
- Create a new [xsdata-style `@dataclass`](https://xsdata.readthedocs.io/en/latest/models.html) model in `src/aiovantage/objects/`
- The new class should inherit from the appropriate subclass expected by the controller
- Your class name should match the Vantage object name if possible, otherwise use [class metadata](https://xsdata.readthedocs.io/en/latest/models.html#class-metadata) to specify the name
- Export the class in `src/aiovantage/config_client/models/__init__.py` so it can be automatically parsed
- Add the object name to the `vantage_types` tuple in the appropriate controller in `src/aiovantage/config_client/controllers/`, so we know to fetch it when populating the controller
- Test that the object appears in the controller, by running the `dump_system.py` example script
- Export the class in `src/aiovantage/objects/__init__.py` so it can be automatically parsed
- Add the object type to the `vantage_types` tuple in the appropriate controller in `src/aiovantage/controllers/`, so we know to fetch it when populating the controller
- Test that the object appears in the controller as expected

### Adding support for a new class of device

Expand All @@ -61,57 +70,48 @@ Good pull requests remain focused in scope and avoid containing unrelated commit

## 🎨 Style guidelines

This project uses [pre-commit](https://pre-commit.com/) to run code linting and formatting checks before commits are made.

To install `pre-commit` and its associated hooks, run the following:

```bash
pip install pre-commit
pre-commit install
```
Before submitting a pull request, make sure your code follows the style guidelines.

To run our linters on the full code base, run the following command:
Use pyright for type checking:

```bash
pre-commit run --all-files
uv run pyright
```

## 📦️ Build a package

To build the package, first bump the version
Use Ruff for linting:

```bash
hatch version <major|minor|patch>
uv run ruff check
```

Then build the package
Use Ruff for formatting:

```bash
hatch build -c
uv run ruff format
```

## 🚀 Publish a release
If you are using vscode, you'll be prompted to install the recommended extensions when you open the workspace.

Follow these steps to publish the release on PyPi.
## 📦️ Build a package

Commit `src/aiovantage/__about__.py` to source control
To build the package, first update the version number:

```bash
git add src/aiovantage/__about__.py
git commit -m "Preparing release `hatch version`"
bumpver update --patch # or --major --minor
```

Tag the release
Then build the package:

```bash
git tag `hatch version`
git push && git push --tags
uv build
```

Publish the release to PyPi
## 🚀 Publish a release

To publish the package to PyPi:

```bash
hatch publish
uv publish
```

Don't forget to [create a release on GitHub](https://github.com/loopj/aiovantage/releases/new).
Don't forget to [create a release on GitHub](https://github.com/loopj/aiovantage/releases/new)!
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ For example, to turn on a load:

```python
async with Vantage("hostname", "username", "password") as vantage:
await vantage.loads.turn_on(118)
load = await vantage.loads.aget(name="Study Lights")
load.turn_on()
```

### Subscribing to state changes
Expand Down
2 changes: 1 addition & 1 deletion examples/anemo_sensors/monitor_anemo_sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any

from aiovantage import Vantage, VantageEvent
from aiovantage.models import AnemoSensor
from aiovantage.objects import AnemoSensor

# Grab connection info from command line arguments
parser = argparse.ArgumentParser(description="aiovantage example")
Expand Down
2 changes: 1 addition & 1 deletion examples/blinds/monitor_blinds.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any

from aiovantage import Vantage, VantageEvent
from aiovantage.models import SystemObject
from aiovantage.objects import SystemObject

# Grab connection info from command line arguments
parser = argparse.ArgumentParser(description="aiovantage example")
Expand Down
2 changes: 1 addition & 1 deletion examples/buttons/monitor_buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any

from aiovantage import Vantage, VantageEvent
from aiovantage.models import Button
from aiovantage.objects import Button

# Grab connection info from command line arguments
parser = argparse.ArgumentParser(description="aiovantage example")
Expand Down
2 changes: 1 addition & 1 deletion examples/dry_contacts/monitor_dry_contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any

from aiovantage import Vantage, VantageEvent
from aiovantage.models import DryContact
from aiovantage.objects import DryContact

# Grab connection info from command line arguments
parser = argparse.ArgumentParser(description="aiovantage example")
Expand Down
Loading
Loading