aiotrimlight 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,49 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ workflow_call:
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ concurrency:
15
+ group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ test:
20
+ name: Test
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - name: Check out repository
24
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
25
+ with:
26
+ persist-credentials: false
27
+ - name: Install uv and Python
28
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
29
+ with:
30
+ python-version: "3.14"
31
+ enable-cache: true
32
+ - name: Install dependencies
33
+ run: uv sync --locked --group test
34
+ - name: Run tests
35
+ run: uv run --no-sync pytest --cov=aiotrimlight --cov-branch --cov-report=term-missing
36
+ - name: Run ruff
37
+ run: |
38
+ uv run --no-sync ruff check .
39
+ uv run --no-sync ruff format --check .
40
+ - name: Run mypy
41
+ run: uv run --no-sync mypy src tests
42
+ - name: Build distributions
43
+ run: uv build --no-sources
44
+ - name: Check distribution metadata
45
+ run: uv run --no-sync twine check dist/*
46
+ - name: Test wheel
47
+ run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
48
+ - name: Test source distribution
49
+ run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
@@ -0,0 +1,79 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - released
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: release-${{ github.event.release.tag_name }}
13
+ cancel-in-progress: false
14
+
15
+ jobs:
16
+ ci:
17
+ uses: ./.github/workflows/ci.yml
18
+ permissions:
19
+ contents: read
20
+
21
+ build:
22
+ name: Build distributions
23
+ needs: ci
24
+ runs-on: ubuntu-latest
25
+ timeout-minutes: 10
26
+ steps:
27
+ - name: Check out repository
28
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
29
+ with:
30
+ persist-credentials: false
31
+ - name: Install uv and Python
32
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
33
+ with:
34
+ python-version: "3.14"
35
+ enable-cache: false
36
+ - name: Validate release tag
37
+ shell: bash
38
+ run: |
39
+ package_version="$(uv version --short)"
40
+ if [[ "${GITHUB_REF_NAME}" != "v${package_version}" ]]; then
41
+ echo "Release tag ${GITHUB_REF_NAME} does not match package version ${package_version}" >&2
42
+ exit 1
43
+ fi
44
+ - name: Install build dependencies
45
+ run: uv sync --locked --group test
46
+ - name: Build distributions
47
+ run: uv build --no-sources --clear
48
+ - name: Check distribution metadata
49
+ run: uv run --no-sync twine check dist/*
50
+ - name: Test wheel
51
+ run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
52
+ - name: Test source distribution
53
+ run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
54
+ - name: Upload distributions
55
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
56
+ with:
57
+ name: python-package-distributions
58
+ path: dist/
59
+ if-no-files-found: error
60
+ retention-days: 7
61
+
62
+ publish:
63
+ name: Publish to PyPI
64
+ needs: build
65
+ runs-on: ubuntu-latest
66
+ timeout-minutes: 10
67
+ environment:
68
+ name: pypi
69
+ url: https://pypi.org/p/aiotrimlight
70
+ permissions:
71
+ id-token: write # Used only for PyPI Trusted Publishing.
72
+ steps:
73
+ - name: Download distributions
74
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
75
+ with:
76
+ name: python-package-distributions
77
+ path: dist/
78
+ - name: Publish distributions
79
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33
@@ -0,0 +1,12 @@
1
+ .venv/
2
+ .coverage
3
+ .DS_Store
4
+ .mypy_cache/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ __pycache__/
8
+ *.egg-info/
9
+ build/
10
+ coverage.xml
11
+ dist/
12
+ htmlcov/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 aiotrimlight contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.5
2
+ Name: aiotrimlight
3
+ Version: 0.2.1
4
+ Summary: Asynchronous client for the Trimlight V3 local HTTP API
5
+ Project-URL: Homepage, https://github.com/spdevpro/trimlight-ha-api
6
+ Project-URL: Source, https://github.com/spdevpro/trimlight-ha-api
7
+ Project-URL: Issues, https://github.com/spdevpro/trimlight-ha-api/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Framework :: AsyncIO
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.14
17
+ Requires-Dist: aiohttp>=3.13.0
18
+ Requires-Dist: yarl>=1.20.0
19
+ Description-Content-Type: text/markdown
20
+
21
+ # aiotrimlight
22
+
23
+ [![CI](https://github.com/spdevpro/trimlight-ha-api/actions/workflows/ci.yml/badge.svg)](https://github.com/spdevpro/trimlight-ha-api/actions/workflows/ci.yml)
24
+
25
+ `aiotrimlight` is an asynchronous Python client for the Trimlight V3 local HTTP API. It provides device metadata, runtime light state, and high-level power, brightness, and static color control.
26
+
27
+ ## Requirements
28
+
29
+ - Python 3.14 or newer.
30
+ - A Trimlight controller with the V3 local HTTP API.
31
+ - The client and controller must be reachable on the same local network.
32
+
33
+ ## Installation
34
+
35
+ ```shell
36
+ python -m pip install aiotrimlight
37
+ ```
38
+
39
+ For source development:
40
+
41
+ ```shell
42
+ git clone https://github.com/spdevpro/trimlight-ha-api.git
43
+ cd aiotrimlight
44
+ uv sync --locked --group test --python 3.14
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ```python
50
+ import asyncio
51
+
52
+ from aiohttp import ClientSession
53
+
54
+ from aiotrimlight import TrimlightClient
55
+
56
+
57
+ async def main() -> None:
58
+ async with ClientSession(trust_env=False) as session:
59
+ client = TrimlightClient("192.0.2.10", session)
60
+
61
+ device = await client.get_device_info()
62
+ state = await client.get_light_state()
63
+ print(device, state)
64
+
65
+ await client.set_light_state(
66
+ on=True,
67
+ brightness=64,
68
+ red=255,
69
+ green=255,
70
+ blue=255,
71
+ warm_white=0,
72
+ cold_white=0,
73
+ )
74
+
75
+
76
+ asyncio.run(main())
77
+ ```
78
+
79
+ Replace the example address with the controller's LAN IP address.
80
+
81
+ `trust_env=False` prevents system proxy settings from routing local controller traffic through an HTTP proxy.
82
+
83
+ ## Development
84
+
85
+ ```shell
86
+ uv sync --locked --group test --python 3.14
87
+ uv run --no-sync pytest --cov=aiotrimlight --cov-branch --cov-report=term-missing
88
+ uv run --no-sync ruff check .
89
+ uv run --no-sync ruff format --check .
90
+ uv run --no-sync mypy src tests
91
+ uv build --no-sources --clear
92
+ uv run --no-sync twine check dist/*
93
+ ```
94
+
95
+ > [!WARNING]
96
+ > `examples/turn_on.py` sends commands to real Trimlight hardware. Review the configured host and output values before running it.
97
+
98
+ ## Releases
99
+
100
+ Stable releases are built and published through GitHub Actions using PyPI
101
+ Trusted Publishing.
102
+
103
+ ## License
104
+
105
+ `aiotrimlight` is distributed under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,85 @@
1
+ # aiotrimlight
2
+
3
+ [![CI](https://github.com/spdevpro/trimlight-ha-api/actions/workflows/ci.yml/badge.svg)](https://github.com/spdevpro/trimlight-ha-api/actions/workflows/ci.yml)
4
+
5
+ `aiotrimlight` is an asynchronous Python client for the Trimlight V3 local HTTP API. It provides device metadata, runtime light state, and high-level power, brightness, and static color control.
6
+
7
+ ## Requirements
8
+
9
+ - Python 3.14 or newer.
10
+ - A Trimlight controller with the V3 local HTTP API.
11
+ - The client and controller must be reachable on the same local network.
12
+
13
+ ## Installation
14
+
15
+ ```shell
16
+ python -m pip install aiotrimlight
17
+ ```
18
+
19
+ For source development:
20
+
21
+ ```shell
22
+ git clone https://github.com/spdevpro/trimlight-ha-api.git
23
+ cd aiotrimlight
24
+ uv sync --locked --group test --python 3.14
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```python
30
+ import asyncio
31
+
32
+ from aiohttp import ClientSession
33
+
34
+ from aiotrimlight import TrimlightClient
35
+
36
+
37
+ async def main() -> None:
38
+ async with ClientSession(trust_env=False) as session:
39
+ client = TrimlightClient("192.0.2.10", session)
40
+
41
+ device = await client.get_device_info()
42
+ state = await client.get_light_state()
43
+ print(device, state)
44
+
45
+ await client.set_light_state(
46
+ on=True,
47
+ brightness=64,
48
+ red=255,
49
+ green=255,
50
+ blue=255,
51
+ warm_white=0,
52
+ cold_white=0,
53
+ )
54
+
55
+
56
+ asyncio.run(main())
57
+ ```
58
+
59
+ Replace the example address with the controller's LAN IP address.
60
+
61
+ `trust_env=False` prevents system proxy settings from routing local controller traffic through an HTTP proxy.
62
+
63
+ ## Development
64
+
65
+ ```shell
66
+ uv sync --locked --group test --python 3.14
67
+ uv run --no-sync pytest --cov=aiotrimlight --cov-branch --cov-report=term-missing
68
+ uv run --no-sync ruff check .
69
+ uv run --no-sync ruff format --check .
70
+ uv run --no-sync mypy src tests
71
+ uv build --no-sources --clear
72
+ uv run --no-sync twine check dist/*
73
+ ```
74
+
75
+ > [!WARNING]
76
+ > `examples/turn_on.py` sends commands to real Trimlight hardware. Review the configured host and output values before running it.
77
+
78
+ ## Releases
79
+
80
+ Stable releases are built and published through GitHub Actions using PyPI
81
+ Trusted Publishing.
82
+
83
+ ## License
84
+
85
+ `aiotrimlight` is distributed under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,46 @@
1
+ """Turn a physical Trimlight controller on through the high-level client API."""
2
+
3
+ import argparse
4
+ import asyncio
5
+
6
+ from aiohttp import ClientSession
7
+
8
+ from aiotrimlight import TrimlightClient
9
+
10
+
11
+ async def async_main(host: str, brightness: int) -> None:
12
+ """Get device information and turn the whole installation on."""
13
+ async with ClientSession(trust_env=False) as session:
14
+ client = TrimlightClient(host, session)
15
+ device_info = await client.get_device_info()
16
+ print(
17
+ "Connected to",
18
+ host,
19
+ f"firmware={device_info.firmware_version}",
20
+ f"ic={device_info.ic_type.name}",
21
+ )
22
+ state = await client.set_light_state(
23
+ on=True,
24
+ brightness=brightness,
25
+ red=255,
26
+ green=255,
27
+ blue=255,
28
+ warm_white=0,
29
+ cold_white=0,
30
+ )
31
+ print(f"Controller reported state: {state}")
32
+
33
+
34
+ def main() -> None:
35
+ """Run the physical-device command."""
36
+ parser = argparse.ArgumentParser(
37
+ description="Turn on a Trimlight controller; this changes a physical light."
38
+ )
39
+ parser.add_argument("--host", required=True)
40
+ parser.add_argument("--brightness", type=int, default=64)
41
+ args = parser.parse_args()
42
+ asyncio.run(async_main(args.host, args.brightness))
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()
@@ -0,0 +1,66 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "aiotrimlight"
7
+ version = "0.2.1"
8
+ description = "Asynchronous client for the Trimlight V3 local HTTP API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.14"
11
+ license = "MIT"
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Framework :: AsyncIO",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.14",
18
+ "Typing :: Typed",
19
+ ]
20
+ dependencies = [
21
+ "aiohttp>=3.13.0",
22
+ "yarl>=1.20.0",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/spdevpro/trimlight-ha-api"
27
+ Source = "https://github.com/spdevpro/trimlight-ha-api"
28
+ Issues = "https://github.com/spdevpro/trimlight-ha-api/issues"
29
+
30
+ [dependency-groups]
31
+ test = [
32
+ "mypy>=1.19.0",
33
+ "pytest>=8.4.0",
34
+ "pytest-asyncio>=1.2.0",
35
+ "pytest-cov>=7.0.0",
36
+ "ruff>=0.13.0",
37
+ "twine>=6.2.0",
38
+ ]
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/aiotrimlight"]
42
+
43
+ [tool.pytest.ini_options]
44
+ addopts = "--strict-markers --strict-config"
45
+ asyncio_mode = "auto"
46
+ testpaths = ["tests"]
47
+
48
+ [tool.coverage.run]
49
+ branch = true
50
+ source = ["aiotrimlight"]
51
+
52
+ [tool.coverage.report]
53
+ fail_under = 100
54
+ show_missing = true
55
+
56
+ [tool.mypy]
57
+ python_version = "3.14"
58
+ strict = true
59
+ files = ["src", "tests"]
60
+
61
+ [tool.ruff]
62
+ target-version = "py314"
63
+ line-length = 88
64
+
65
+ [tool.ruff.lint]
66
+ select = ["ASYNC", "B", "E", "F", "I", "RUF", "SIM", "UP"]
@@ -0,0 +1,35 @@
1
+ """Asynchronous Trimlight V3 HTTP client."""
2
+
3
+ from .client import TrimlightClient
4
+ from .discovery import parse_discovery_properties
5
+ from .exceptions import (
6
+ TrimlightCommandError,
7
+ TrimlightConnectionError,
8
+ TrimlightDiscoveryError,
9
+ TrimlightError,
10
+ TrimlightHTTPError,
11
+ TrimlightProtocolError,
12
+ TrimlightUnsupportedICError,
13
+ )
14
+ from .models import (
15
+ TrimlightDeviceInfo,
16
+ TrimlightDiscoveryInfo,
17
+ TrimlightICType,
18
+ TrimlightLightState,
19
+ )
20
+
21
+ __all__ = [
22
+ "TrimlightClient",
23
+ "TrimlightCommandError",
24
+ "TrimlightConnectionError",
25
+ "TrimlightDeviceInfo",
26
+ "TrimlightDiscoveryError",
27
+ "TrimlightDiscoveryInfo",
28
+ "TrimlightError",
29
+ "TrimlightHTTPError",
30
+ "TrimlightICType",
31
+ "TrimlightLightState",
32
+ "TrimlightProtocolError",
33
+ "TrimlightUnsupportedICError",
34
+ "parse_discovery_properties",
35
+ ]