Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

OWNd

PyPI version Python versions CI License: LGPL-3.0 Ruff Coverage Codecov

OWNd is an asynchronous Python library and daemon for the Legrand / BTicino OpenWebNet home automation protocol.

It powers the Home Assistant MyHOME integration and serves as a standalone Python client for discovering, monitoring, and controlling OpenWebNet bus devices over TCP/IP gateways and serial USB interfaces.


Key Features

  • Hardened Dual-Session Architecture: Decouples real-time bus event monitoring (OWNEventSession) from command and query execution (OWNCommandSession), preventing command bursts from interrupting event monitoring.
  • Serial & USB Dongle Support: Built-in single-channel serial transport (AsyncSerialTransport) for the Legrand 3578 USB/ZigBee interface with in-band event and command-reply demultiplexing.
  • Connection Resilience:
    • Fail-closed SHA-1 and HMAC-SHA2 gateway authentication with constant-time signature verification.
    • OS-level TCP keepalive (SO_KEEPALIVE) with aggressive probing (30s idle / 10s interval / 3 count) to detect silent network drops (power loss, cable unplugged) in ~60s.
    • Periodic application-level keepalives and passive watchdogs.
    • Non-blocking bounded timeouts on handshakes and commands to prevent event loop stalls.
    • Multi-frame response collection for large bus status sweeps (up to 256 frames).
  • Declarative Hardware Profiles: Tailored queue pacing, session concurrency, and subsystem limits for known Legrand/BTicino hardware (F454, F455, MH200N, MH201, MH202, MyHomeServer1, and conservative generic fallbacks).
  • Modern Python: Designed for Python 3.11+, tested continuously against Python 3.11, 3.12, 3.13, and 3.14.

Installation

Install the latest stable release from PyPI:

pip install OWNd

To test preview releases or beta builds:

pip install --pre OWNd

Optional Extras

  • Serial / USB support (required for Legrand 3578 USB dongles):
    pip install "OWNd[serial]"
    
  • Development & test suite:
    pip install "OWNd[test]"
    

Supported Subsystems (WHO Catalog)

OWNd parses OpenWebNet frames and dispatches typed commands and events across the full MyHOME spectrum:

WHO Subsystem Description & Capabilities Event / Command Classes
1 Lighting On/off switching, dimming level (0–100%), status queries OWNLightingCommand, OWNLightingEvent
2 Automation Shutters, blinds, motorized curtains, tilt angles, short & full replies OWNAutomationCommand, OWNAutomationEvent
3 Load Control Load shedding status, circuit priority management OWNCommand, OWNEvent
4 Thermoregulation / Climate Multi-zone temperature readouts, target adjustments, HVAC modes (Heat/Cool/Auto/Off), local offsets, fan coil speeds, valve states OWNHeatingCommand, OWNHeatingEvent
5 Burglar Alarm Zone status, system arming / disarming states OWNAlarmCommand, OWNAlarmEvent
13 Gateway Diagnostics & Clock Gateway date/time synchronization, timezone offsets, firmware metadata OWNGatewayCommand, OWNGatewayEvent
15 CEN Scenarios Scenario control, pushbutton push/release/extended press events OWNCENEvent, OWNScenarioEvent
16 / 22 Sound Diffusion Multi-source selection, zone activation, volume adjustment, F441 matrix OWNSoundCommand, OWNSoundEvent, OWNAVCommand
17 Scenario Programmer MH200N / MH202 scenario activation and state monitoring OWNSceneEvent
18 Energy Management Active power (W), hourly/daily/monthly consumption (kWh), Stop & Go breaker diagnostics OWNEnergyCommand, OWNEnergyEvent
25 CEN+ & Dry Contacts 32-button keypads, rotary knob encoders (CW/CCW), dry contacts, PIR sensors OWNCENPlusEvent, OWNDryContactCommand, OWNDryContactEvent

Hardware Gateway Profiles

Gateways have varying processing limitations, socket budgets, and pacing requirements. OWNd uses declarative profiles to protect your hardware:

Gateway Model Concurrency Queue Delay Keepalive Features
MyHomeServer1 4 sessions (2 default) 20 ms Profile HMAC-SHA2, Native transitions, Extended frames
F454 / F455 4 sessions 50 ms 90 s HMAC-SHA2, Native transitions, Extended frames
MH202 2 sessions 100 ms Profile HMAC-SHA2, Extended frames
MH201 1 session 100 ms Profile Extended frames, Clock diagnostics
MH200N 1 session 150 ms 90 s Safe pacing, Legacy password auth
Generic Gateway 1 session 50 ms Profile Conservative fallback

Profiles can be resolved automatically using get_gateway_profile(model_name):

from OWNd.profiles import get_gateway_profile

profile = get_gateway_profile("F454")
print(f"Max concurrent sessions: {profile.max_command_sessions}")
print(f"Command queue delay: {profile.command_queue_delay}s")

Quick Start

1. High-Level TCP Transport (Dual-Session)

import asyncio
from OWNd.connection import OWNGateway
from OWNd.transport.tcp import AsyncTcpTransport
from OWNd.message import OWNMessage

async def main():
    # Configure gateway credentials
    gateway = OWNGateway({
        "address": "192.168.1.50",
        "port": 20000,
        "password": "12345",
    })

    transport = AsyncTcpTransport(gateway)

    # Register an event listener for bus notifications
    def on_event(msg: OWNMessage | str):
        if isinstance(msg, OWNMessage) and msg.is_event:
            print(f"Bus Event: {msg.human_readable_log}")

    transport.register_listener(on_event)

    # Connect both event and command channels
    if await transport.connect():
        print("Connected to OpenWebNet gateway!")

        # Send a command: Turn ON light at address 12 (*1*1*12##)
        response = await transport.send("*1*1*12##")
        print(f"Command response: {response}")

        # Keep listening for events
        await asyncio.sleep(10)
        await transport.disconnect()

if __name__ == "__main__":
    asyncio.run(main())

2. Direct Session Management

For fine-grained control, OWNEventSession and OWNCommandSession can be operated independently:

import asyncio
from OWNd.connection import OWNGateway, OWNEventSession, OWNCommandSession

async def main():
    gateway = OWNGateway({"address": "192.168.1.50", "port": 20000, "password": "12345"})

    # Event listening session
    event_session = OWNEventSession(gateway=gateway)
    await event_session.connect()

    # Command session
    command_session = OWNCommandSession(gateway=gateway)
    await command_session.connect()

    # Query status of zone 1 climate: *#4*1*0##
    status = await command_session.send("*#4*1*0##", is_status_request=True)
    print(f"Status response: {status}")

    await event_session.close()
    await command_session.close()

asyncio.run(main())

3. Serial / USB Dongle (Legrand 3578)

import asyncio
from OWNd.transport.serial import AsyncSerialTransport

async def main():
    transport = AsyncSerialTransport(port="/dev/ttyUSB0")
    transport.register_listener(lambda msg: print(f"Serial Inbound: {msg}"))

    await transport.connect()
    # Send OpenWebNet frame over serial
    await transport.send("*1*1*12##")

    await asyncio.sleep(5)
    await transport.disconnect()

asyncio.run(main())

Command Line Interface (CLI)

OWNd includes a built-in CLI for discovering gateways and inspecting live bus events:

Auto-Discovery (SSDP)

Scan the local network for OpenWebNet gateways and listen for events:

python -m OWNd

Direct Connection

Connect to a known gateway IP address:

python -m OWNd --address 192.168.1.50 --port 20000 --password 12345 --verbose 2

Available options:

  • -a, --address: IP address of the gateway
  • -p, --port: Gateway TCP port (default: 20000)
  • -P, --password: Numeric OPEN password or HMAC secret (default: 12345)
  • -m, --mac: MAC address (used as unique identifier when skipping SSDP)
  • -v, --verbose: Verbosity level (0 = WARNING, 1 = INFO, 2 = DEBUG)

Development

Clone the repository and install development dependencies:

git clone https://github.com/OpenWebNet-HA/OWNd.git
cd OWNd
pip install -e ".[test,serial]" ruff mypy types-python-dateutil types-pytz

Running Tests

Execute the test suite across all subsystems:

python -m pytest -q

Static Analysis & Linting

Verify type safety and coding standards:

ruff check OWNd tests setup.py
mypy OWNd

License

This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0-only). See the LICENSE file for details.

📊 Code Coverage & Quality Assurance

OWNd maintains an automated unit test suite with strict line coverage tracking across all core modules:

Component / Module Coverage Notes
OWNd/__init__.py 100% Package initialization and version metadata
OWNd/discovery.py 100% SSDP multicast and UPnP XML gateway discovery and descriptor parsing
OWNd/profiles.py 100% Declarative hardware gateway models (F454, MH200N, MH201, MH202, MyHomeServer1)
OWNd/transport/__init__.py 100% Transport subpackage exports
OWNd/transport/base.py 100% Abstract transport layer and event listener notification contracts
OWNd/transport/tcp.py 100% Dual-session TCP transport linking event and command channels
OWNd/message.py 100% OpenWebNet frame parsers, encoders, and WHO dimension decoders
OWNd/connection.py 100% Hardened dual-session TCP engine, SHA-1/HMAC auth, keepalives & bounded read loops
OWNd/transport/serial.py 100% Async Serial/USB transport for Legrand 3578 interface with in-band demux

Live Test Execution: View detailed line-by-line coverage and test history on Codecov (OpenWebNet-HA/OWNd) or download the interactive coverage report from the CI GitHub Actions run.

Release files for OWNd 2.0.0b2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for OWNd 2.0.0b2
File Size Uploaded
ownd-2.0.0b2.tar.gz 83.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for OWNd 2.0.0b2
File Interpreter ABI Platform
ownd-2.0.0b2-py3-none-any.whl Python 3 none any Details

Total release size: 132.6 kB

Release files / ownd-2.0.0b2.tar.gz

Download URL ownd-2.0.0b2.tar.gz
Size 83.2 kB
Tags Source
SHA-256 checksum
How to use checksums
61a07b4c3632079b0b6b920c4ca06c3eea0b4e15aa2308b62ed3b00396bcb01b
BLAKE2b-256 checksum
How to use checksums
ba4e9146e2c387efa3bb1b5d7209688065b858f59b7a0eb8b62b3365a7771664
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / ownd-2.0.0b2-py3-none-any.whl

Download URL ownd-2.0.0b2-py3-none-any.whl
Size 49.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b5065b9541cf0f5351b8e7391f88c3f6c6be096cba1862e035fcc858a224f7f2
BLAKE2b-256 checksum
How to use checksums
bac01c70bdd3847e7403cb9f735c5f21e828c7e20b6ee1516deff2dbc2053d41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.0.0b2 This release

2 release files

0.7.49

2 release files

0.7.48

2 release files

0.7.47

2 release files

0.7.46

2 release files

0.7.45

2 release files

0.7.44

2 release files

0.7.42

2 release files

0.7.41

2 release files

0.7.40

2 release files

0.7.39

2 release files

0.7.37

2 release files

0.7.36

2 release files

0.7.35

2 release files

0.7.34

2 release files

0.7.33

2 release files

0.7.32

2 release files

0.7.31

2 release files

0.7.30

2 release files

0.7.27

2 release files

0.7.24

2 release files

0.7.23

2 release files

0.7.22

2 release files

0.7.21

2 release files

0.7.20

2 release files

0.7.19

2 release files

0.7.18

2 release files

0.7.17

2 release files

0.7.16

2 release files

0.7.15

2 release files

0.7.11

2 release files

0.7.10

2 release files

0.7.9

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.6.19

2 release files

0.6.18

2 release files

0.6.17

2 release files

0.6.16

2 release files

0.6.15

2 release files

0.6.14

2 release files

0.6.13

2 release files

0.6.12

2 release files

0.6.11

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page