Metadata-Version: 2.4
Name: knxyz
Version: 0.0.8
Summary: KNXnet/IP clients and .knxproj loading for Python.
Keywords: building-automation,home-automation,knx,knxnet-ip
Author-email: goznauk <goznauk@naver.com>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Documentation, https://knxyz.io
Project-URL: Homepage, https://knxyz.io
Project-URL: Issues, https://github.com/goznauk/KNXyz/issues
Project-URL: Repository, https://github.com/goznauk/KNXyz

# knxyz

KNXyz for Python: KNXnet/IP clients and `.knxproj` loading.

## Install

```sh
pip install knxyz
```

## Host values

An omitted item composes as the row's zero default, so `{}` asks for every
declared item at its zero default and `write(ga, {}, "9.001")` transmits
0.0 degree C. An explicit `None` is a different request: where the row
declares an invalid marker, `None` asks for that marker.

A host value the document cannot carry faithfully is refused before any
document, frame or socket work exists, so a refused call sends nothing at
all. `None`, `bool`, `int`, a finite `float`, `str`, `list`, `tuple` and
`dict` with string keys are carried, including a subclass that stores no
instance state of its own. A `set`, `bytes`, a `Decimal`, a non-`dict`
Mapping, an arbitrary object, a `dict` carrying a key that is not a string,
a subclass carrying instance state the document has nowhere to put and a
subclass whose class will not say where its instance state is are
refused with a `KnxError` whose `code` is `host/non-finite-number`,
`host/unrepresentable-value`, `host/circular-structure` or
`host/value-too-complex`.

## Errors

A refused KNX operation raises a `KnxError` carrying a `code`, a
hierarchical path whose first segment names the authority that refused and
picks the subclass raised. A mistake in the shape of an options object is a
different layer and a different class: it raises a plain `ValueError` naming
the key, because the remedy is a fix at the call site rather than a branch
on a wire code.

## Threads

The address helpers and `.knxproj` loading hold no state of their own and
are callable from any thread. A client object serializes its own state:
the native tunnel and routing clients each guard their transport and their
monitor subscription with their own locks, so calls on one client from
several threads interleave rather than race, and a second `monitor_next`
while one is pending is refused rather than admitted. The GIL is released
around every call that blocks on the transport, so a blocked send, monitor
wait or close does not stop other Python threads. The value and option
judgements run before that release, which is why a refused call is refused
without touching a socket.

## `.knxproj` loading

```python
from knxyz import load_knxproj

project = load_knxproj("project.knxproj")
print(len(project.group_addresses))
```

The knxyz.io documentation tracks the source in the repository. A published
version can be built from different source under the same version number, so
those pages may describe API this package version does not carry.

Documentation: https://knxyz.io<br>
Repository: https://github.com/goznauk/KNXyz

