Skip to content

Commit e9106be

Browse files
Add initial configuration for CI and package
1 parent 3f82aad commit e9106be

4 files changed

Lines changed: 168 additions & 24 deletions

File tree

.github/workflows/ci.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CI (Test & Lint)
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test-and-lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Python
16+
uses: actions/setup-python@v5
17+
with:
18+
python-version: '3.12'
19+
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install .[dev]
24+
25+
- name: Lint with Ruff
26+
run: |
27+
ruff check .
28+
29+
- name: Run Tests with Pytest
30+
run: |
31+
export PYTHONPATH=src
32+
python -m pytest tests/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Martin
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.

README.md

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,63 @@
11
# knx-telegram-store
22

3-
A standalone, host-agnostic Python library for KNX telegram persistence with pluggable storage backends.
4-
5-
## Motivation
6-
7-
KNX telegram storage is needed in multiple projects — [Home Assistant KNX](https://www.home-assistant.io/integrations/knx/) and [SpectrumKNX](https://github.com/spectrumknx/spectrumknx) — but currently each implements its own storage layer with zero shared code. This library extracts a common interface and ships multiple backends so both projects (and others) can share the same well-tested storage implementation.
3+
A standalone, host-agnostic Python library for KNX telegram persistence.
84

95
## Features
106

11-
- **Canonical data model** — A single `StoredTelegram` dataclass covering all KNX telegram fields.
12-
- **Abstract storage interface**`TelegramStore` ABC with pluggable backends.
13-
- **Declarative query model**`TelegramQuery` supports multi-value filters, time ranges, time-delta context windows, and pagination.
14-
- **Graceful degradation** — Simple backends return all data; consumers apply client-side filtering. SQL backends filter server-side.
15-
- **Zero core dependencies** — The core library (model + interface + in-memory backend) has no runtime dependencies.
7+
- **Canonical Data Model**: A unified model for KNX telegrams shared between Home Assistant and SpectrumKNX.
8+
- **Pluggable Backends**:
9+
- **In-Memory**: Fast, deque-based storage with full filtering support.
10+
- **SQLite**: Lightweight persistent storage with SQL-based filtering.
11+
- **PostgreSQL + TimescaleDB**: Full-scale time-series storage.
12+
- **Unified Query Model**: Powerful declarative filtering including time-delta context windows and pagination.
13+
- **Zero Runtime Dependencies**: Core library (model, interface, in-memory) has no dependencies.
14+
- **Automated Schema Management**: SQL backends handle their own creation and upgrades.
1615

17-
## Backends
16+
## Installation
1817

19-
| Backend | Use Case | Dependencies |
20-
|---|---|---|
21-
| **In-Memory** | Testing, development | None |
22-
| **HA Storage** | Home Assistant native persistence | None (uses HA's `Store`) |
23-
| **SQLite** | Lightweight persistent storage | `aiosqlite` |
24-
| **PostgreSQL + TimescaleDB** | Full-scale time-series storage | `asyncpg`, `sqlalchemy` |
18+
```bash
19+
pip install knx-telegram-store
20+
```
2521

26-
## Installation
22+
For SQL support:
2723

2824
```bash
29-
pip install knx-telegram-store # Core only
30-
pip install knx-telegram-store[sqlite] # + SQLite backend
31-
pip install knx-telegram-store[postgres] # + PostgreSQL backend
25+
pip install knx-telegram-store[sqlite]
26+
pip install knx-telegram-store[postgres]
3227
```
3328

34-
## Documentation
29+
## Usage
3530

36-
See [docs/design_and_implementation.md](docs/design_and_implementation.md) for the full design document.
31+
```python
32+
from datetime import datetime
33+
from knx_telegram_store import StoredTelegram, TelegramQuery
34+
from knx_telegram_store.backends.memory import MemoryStore
35+
36+
async def main():
37+
store = MemoryStore(max_size=1000)
38+
await store.initialize()
39+
40+
telegram = StoredTelegram(
41+
timestamp=datetime.now(),
42+
source="1.1.1",
43+
destination="1/1/1",
44+
telegramtype="GroupValueWrite",
45+
direction="Incoming",
46+
value=22.5,
47+
unit="°C"
48+
)
49+
50+
await store.store(telegram)
51+
52+
query = TelegramQuery(destinations=["1/1/1"])
53+
result = await store.query(query)
54+
55+
for t in result.telegrams:
56+
print(f"{t.timestamp}: {t.source} -> {t.destination} | {t.value} {t.unit}")
57+
58+
await store.close()
59+
```
3760

3861
## License
3962

40-
Apache License 2.0
63+
MIT

pyproject.toml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "knx-telegram-store"
7+
version = "0.1.0"
8+
description = "A standalone, host-agnostic Python library for KNX telegram persistence."
9+
readme = "README.md"
10+
requires-python = ">=3.12"
11+
license = {text = "MIT"}
12+
authors = [
13+
{name = "Martin Hoefling"}
14+
]
15+
keywords = ["knx", "home-assistant", "persistence", "storage", "telegram"]
16+
classifiers = [
17+
"Development Status :: 3 - Alpha",
18+
"Intended Audience :: Developers",
19+
"License :: OSI Approved :: MIT License",
20+
"Programming Language :: Python :: 3.12",
21+
"Topic :: Home Automation",
22+
"Framework :: AsyncIO",
23+
]
24+
dependencies = []
25+
26+
[project.urls]
27+
Homepage = "https://github.com/mar-v-in/knx-telegram-store"
28+
Bug-Tracker = "https://github.com/mar-v-in/knx-telegram-store/issues"
29+
30+
[tool.setuptools.packages.find]
31+
where = ["src"]
32+
include = ["knx_telegram_store*"]
33+
34+
[project.optional-dependencies]
35+
sqlite = ["aiosqlite>=0.20"]
36+
postgres = ["asyncpg>=0.29", "sqlalchemy[asyncio]>=2.0"]
37+
dev = [
38+
"pytest>=8.0",
39+
"pytest-asyncio>=0.23",
40+
"pytest-cov>=4.1",
41+
"ruff>=0.3",
42+
"aiosqlite>=0.20"
43+
]
44+
45+
[tool.ruff]
46+
target-version = "py312"
47+
line-length = 120
48+
exclude = [
49+
".git",
50+
"__pycache__",
51+
".venv",
52+
"venv",
53+
"dist",
54+
]
55+
56+
[tool.ruff.lint]
57+
select = ["E", "F", "B", "I", "U", "UP"]
58+
ignore = [
59+
"E501", # Line too long
60+
]
61+
62+
[tool.ruff.lint.mccabe]
63+
max-complexity = 15
64+
65+
[tool.pytest.ini_options]
66+
asyncio_mode = "auto"
67+
testpaths = ["tests"]
68+
pythonpath = ["src"]

0 commit comments

Comments
 (0)