Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3d51669
move `DeviceChannel` from `mqtt.api` to `mqtt`
rnovatorov Oct 2, 2025
7a254c8
mqtt: export `Message`
rnovatorov Oct 2, 2025
b880fde
mqtt: define api more explicitly
rnovatorov Oct 2, 2025
23bb68d
drop `types` module
rnovatorov Oct 17, 2025
9c27924
mqtt: move `DeviceChannel` back to `api`
rnovatorov Oct 17, 2025
507563d
use `src` dir for package layout
rnovatorov Oct 17, 2025
da1deae
mqtt: api: CommandState: add `LOG`
rnovatorov Oct 20, 2025
07a5a22
drop `vucm` package and tests
rnovatorov Oct 20, 2025
6ffa23c
add `standalone` package
rnovatorov Oct 21, 2025
60043d9
mqtt: api: define one class per file
rnovatorov Oct 21, 2025
0ef188f
standalone: rework device into abc to allow for convenient logging
rnovatorov Oct 22, 2025
ca83c44
drop `async_.Routine` in favor of `asyncio.TaskGroup`
rnovatorov Oct 22, 2025
b1dbf3c
mqtt: fix handling of cancellation during client connection
rnovatorov Oct 23, 2025
8238eab
setup: add `httpx` to dependencies
rnovatorov Oct 23, 2025
5805efe
add basic http api support
rnovatorov Oct 23, 2025
e545670
standalone: device: allow configuring `cmd_prefix`
rnovatorov Oct 24, 2025
dd5c488
config: normalize working with env vars
rnovatorov Oct 27, 2025
b974509
lint: isort: set profile to black
rnovatorov Oct 27, 2025
9795669
mqtt: client: do not log when publisher disconnected
rnovatorov Oct 28, 2025
7c00ccc
http: api: devices: fix time sync protocol parsing
rnovatorov Oct 28, 2025
6f0820d
standalone: rework configuration to support api v3
rnovatorov Oct 28, 2025
7e813f1
typing: modernize annotations
rnovatorov Oct 28, 2025
f62eb3f
drop support for python < 3.11
rnovatorov Oct 29, 2025
8987966
examples: rename `vucm` into `standalone`
rnovatorov Oct 29, 2025
b052a39
standalone: split device protocol and base class
rnovatorov Oct 30, 2025
0d0a6ed
examples: standalone: fix psutil-battery
rnovatorov Oct 30, 2025
c0fef17
examples: standalone: fix rl6-simulator
rnovatorov Oct 30, 2025
a4fa27d
examples: standalone: fix wttr-in
rnovatorov Oct 30, 2025
acc9f15
examples: standalone: fix smart fan
rnovatorov Oct 30, 2025
f33eec1
standalone: device: wrap command result in object
rnovatorov Oct 30, 2025
21055f9
tests: unit: mqtt: fix missing alerts null field
rnovatorov Oct 30, 2025
82b87bb
standalone: ucm: use different intervals for sending properties and t…
rnovatorov Nov 3, 2025
70f7d2e
standalone: app: propagate `CancelledError`
rnovatorov Nov 3, 2025
07dfd72
examples: standalone: try to fix snmp-eaton-ups
rnovatorov Nov 3, 2025
a5b1a35
examples: standalone: try to fix zigbee2mqtt
rnovatorov Nov 3, 2025
58d7bdb
examples: mqtt: drop rl6sim
rnovatorov Nov 3, 2025
c5f1e83
examples: mqtt: fix pub_sub
rnovatorov Nov 3, 2025
725759d
standalone: communication config: allow overriding MQTT host
rnovatorov Nov 3, 2025
d6c7fbe
standalone: run: accept `DeviceProtocol` instead of `Device`
rnovatorov Nov 4, 2025
885d22a
bump version to 0.12.0
rnovatorov Nov 4, 2025
77a1fc5
setup: add type annotations
rnovatorov Nov 4, 2025
5f73628
add `py.typed` marker file
rnovatorov Nov 4, 2025
3df39b0
lint: mypy: check setup and tests
rnovatorov Nov 4, 2025
7dda25b
standalone: Device: make `logger` property sync
rnovatorov Nov 10, 2025
954434b
examples: standalone: fix wttr-in alerts and config env var
rnovatorov Nov 10, 2025
cb62bf9
standalone: config: support ENAPTER_VUCM_BLOB with deprecation warning
rnovatorov Nov 10, 2025
c264cc7
update README to reflect changes
rnovatorov Nov 10, 2025
fc19af4
examples: http: add `get_device_by_id`
rnovatorov Nov 10, 2025
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python: ["3.11", "3.12", "3.13", "3.14"]
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[settings]
known_first_party=enapter
profile=black
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ lint-pyflakes:

.PHONY: lint-mypy
lint-mypy:
pipenv run mypy enapter
pipenv run mypy setup.py
pipenv run mypy tests
pipenv run mypy src/enapter

.PHONY: test
test: run-unit-tests run-integration-tests
Expand Down Expand Up @@ -69,7 +71,7 @@ bump-version:
ifndef V
$(error V is not defined)
endif
sed -E -i 's/__version__ = "[0-9]+.[0-9]+.[0-9]+"/__version__ = "$(V)"/g' enapter/__init__.py
sed -E -i 's/__version__ = "[0-9]+.[0-9]+.[0-9]+"/__version__ = "$(V)"/g' src/enapter/__init__.py

grep -E --files-with-matches --recursive 'enapter==[0-9]+.[0-9]+.[0-9]+' examples \
| xargs -n 1 sed -E -i 's/enapter==[0-9]+.[0-9]+.[0-9]+/enapter==$(V)/g'
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ pytest-asyncio = "*"
pytest-cov = "*"
setuptools = "*"
twine = "*"
types-docker = "*"
types-setuptools = "*"
101 changes: 30 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,89 +6,48 @@

Enapter software development kit for Python.

## Features

- [Standalone
Devices](https://v3.developers.enapter.com/docs/standalone/introduction)
framework.
- [MQTT
API](https://v3.developers.enapter.com/reference/device_integration/mqtt_api/)
client.
- [HTTP API](https://v3.developers.enapter.com/reference/http/intro) client.

## Installation

This project uses [semantic versioning](https://semver.org/).
> [!IMPORTANT]
> Make sure you are using Python 3.11+.

The API is still under development and may change at any time. It is
recommended to pin the version during installation.
> [!WARNING]
> The API is still under development and may change at any time. It is
> recommended to pin the version during installation.

Latest from PyPI:
From PyPI:

```bash
pip install enapter==0.11.3
pip install enapter==0.12.0
```

## Usage

Checkout [examples](examples).

## Implementing your own VUCM

### Device Telemetry and Properties

Every method of `enapter.vucm.Device` subclass decorated with
`enapter.vucm.device_task` decorator is considered a _device task_. When such a
device is started, all of its tasks are started as well. Device tasks are
started in random order and are being executed concurrently in the background.
If a device task returns or raises an exception, device routine is terminated.
A typical use of the task is to run a periodic job to send device telemetry and
properties.

In order to send telemetry and properties define two corresponding device
tasks. It is advised (but is not obligatory) to send telemetry every **1
second** and to send properties every **10 seconds**.

Examples:

- [wttr-in](examples/vucm/wttr-in)

### Device Command Handlers

Every method of `enapter.vucm.Device` subclass decorated with
`enapter.vucm.device_command` is considered a _device command handler_. Device
command handlers receive the same arguments as described in device Blueprint
manifest and can optionally return a payload as `enapter.types.JSON`.

In order to handle device commands define corresponding device command
handlers.

Examples:
Check out examples:

- [zhimi-fan-za5](examples/vucm/zhimi-fan-za5)
- [Standalone Devices](examples/standalone)
- [MQTT API](examples/mqtt)
- [HTTP API](examples/http)

### Device Alerts
They provide a good overview of available features and should give you enough
power to get started.

Device alerts are stored in `self.alerts`. It is a usual Python `set`, so you
can add an alert using `alerts.add`, remove an alert `alerts.remove` and clear
alerts using `alerts.clear`.
> [!TIP]
> Don't hesitate to peek into the source code - it is supposed to be easy to
> follow.

Alerts are sent only as part of telemetry, so in order to report device alert,
use `send_telemetry` with any payload.
## Help

## Running your own VUCM via Docker

A simple Dockerfile can be:

```
FROM python:3.10-alpine3.16

WORKDIR /app

RUN python -m venv .venv
COPY requirements.txt requirements.txt
RUN .venv/bin/pip install -r requirements.txt

COPY script.py script.py

CMD [".venv/bin/python", "script.py"]
```

:information_source: If you are using [Enapter
Gateway](https://handbook.enapter.com/software/gateway_software/) and running
Linux, you should connect your containers to `host` network
:information_source::

```bash
docker run --network host ...
```
If you feel lost or confused, reach us in
[Discord](https://discord.com/invite/TCaEZs3qpe) or just [file a
bug](https://github.com/Enapter/python-sdk/issues/new). We'd be glad to help.
13 changes: 0 additions & 13 deletions enapter/__init__.py

This file was deleted.

7 changes: 0 additions & 7 deletions enapter/async_/__init__.py

This file was deleted.

70 changes: 0 additions & 70 deletions enapter/async_/routine.py

This file was deleted.

11 changes: 0 additions & 11 deletions enapter/mqtt/api/__init__.py

This file was deleted.

51 changes: 0 additions & 51 deletions enapter/mqtt/api/command.py

This file was deleted.

Loading