Skip to main content

Python SDK for Homie MQTT Convention (eBus)

Project description

ebus-sdk

PyPI Ruff

Python SDK for the Electrification Bus (eBus) integration framework, which adopts and supports the Homie Convention.

Installation

pip install ebus-sdk

Quick Start

Device Role

Create a Homie device that publishes sensor data:

from ebus_sdk import Device, Node, PropertyDatatype, Unit

# Create device
device = Device('my-device-id', name='My Sensor', mqtt_cfg={
    'host': 'mqtt.example.com',
    'port': 1883
})

# Add a node with properties
node = device.add_node_from_dict({
    'id': 'sensors',
    'name': 'Sensors',
    'type': 'sensor'
})

# Add a temperature property
temp = node.add_property_from_dict({
    'id': 'temperature',
    'name': 'Temperature',
    'datatype': PropertyDatatype.FLOAT,
    'unit': Unit.DEGREE_CELSIUS
})

# Start and publish
device.start_mqtt_client()
temp.set_value(23.5)

Device Trees (parent / child)

Build a tree of devices that share a single MQTT connection. The root device owns the connection (and the Last Will), every child borrows it via the parent= constructor arg, and $description root / parent / children fields are kept in sync automatically. The tree can be any depth.

panel = Device('panel-1', type='energy.ebus.device.electrical-panel', mqtt_cfg={...})
panel.start_mqtt_client()

# Add 32 circuit children inside one state transition — the broker sees
# exactly one INIT→READY cycle on the panel, not 32.
with panel.state_transition():
    for cid in commissioned_circuits:
        Device(id=cid, type='energy.ebus.device.circuit', parent=panel)

# Three-level tree: panel → BESS child → MID grandchild
bess = Device(id='bess-1', type='...battery-storage', parent=panel)
Device(id='mid-1', type='...metering', parent=bess)

# Remove a child at runtime (runs the Homie remove-child protocol)
panel.children()[0].delete()

Children may have children of their own. A single Last Will registered on the root marks the entire tree lost if the publisher process dies — controllers compute effective state per the Homie 5 precedence table (see HOMIE_EFFECTIVE_STATE_TABLE).

Controller Role

Discover and monitor Homie devices:

from ebus_sdk import Controller, DiscoveredDevice

def on_device_discovered(device: DiscoveredDevice):
    print(f'Found: {device.device_id}')

def on_property_changed(device_id, node_id, prop_id, new_val, old_val):
    print(f'{device_id}/{node_id}/{prop_id} = {new_val}')

controller = Controller(mqtt_cfg={'host': 'mqtt.example.com', 'port': 1883})
controller.set_on_device_discovered_callback(on_device_discovered)
controller.set_on_property_changed_callback(on_property_changed)
controller.start_discovery()

Controllers can also navigate device hierarchies and compute effective state:

# Walk the tree
roots = controller.get_root_devices()
for root in roots:
    for descendant in controller.get_descendants(root.device_id):
        # When the root is lost/disconnected/sleeping/init, every descendant
        # is effectively the same regardless of its own reported $state.
        print(f'{descendant.device_id}: {controller.get_effective_state(descendant.device_id)}')

Module Structure

src/ebus_sdk/
├── __init__.py     # Package exports
├── homie.py        # Homie convention implementation (Device, Node, Property, Controller, ...)
└── property.py     # Application-level property abstractions

MQTT transport lives in the separate ebus-mqtt-client package; this SDK depends on it.

homie.py

Core Homie convention implementation:

  • Device - Represents a Homie device; pass parent= to build a child in a tree
  • Node - Groups related properties within a device
  • Property - Individual data points (sensors, controls)
  • Controller - Discovers and monitors Homie devices on a broker; navigates trees and computes effective state
  • DiscoveredDevice - Represents a device found by the controller; exposes root_id, parent_id, children_ids, is_root
  • DeviceState - Enum: init, ready, disconnected, sleeping, lost
  • HOMIE_EFFECTIVE_STATE_TABLE - Homie 5 state-precedence table used by Controller.get_effective_state()
  • PropertyDatatype - Enum: STRING, INTEGER, FLOAT, BOOLEAN, ENUM, COLOR, DATETIME, DURATION, JSON
  • Unit - Common units: DEGREE_CELSIUS, PERCENT, WATT, KILOWATT_HOUR, etc.

property.py

Application-level property abstractions for bridging application state to Homie:

  • Property - Thread-safe observable property with change callbacks
  • GroupedPropertyDict - Two-level dictionary organizing properties by group
  • PropertyDict - Simple property dictionary
  • ChangeEvent - Enum for property change event types

Examples

See examples/README.md for example scripts demonstrating device and controller usage.

Requirements

  • Python 3.10+
  • paho-mqtt >= 1.6.1

Releases

See CHANGELOG.md. 0.2.0 introduces parent/child device trees and contains breaking changes to the Device constructor — see the changelog entry before upgrading from 0.1.x.

Contributing

See CONTRIBUTING.md for how to file Discussions, Issues, and pull requests. Pure MQTT-transport changes (TLS, auth, paho upgrades) belong in ebus-mqtt-client, not here. Normative behavior tracks the Electrification Bus specification.

License

MIT License — Copyright (c) 2026 Clark Communications Corporation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ebus_sdk-0.2.0.tar.gz (46.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ebus_sdk-0.2.0-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

Details for the file ebus_sdk-0.2.0.tar.gz.

File metadata

  • Download URL: ebus_sdk-0.2.0.tar.gz
  • Upload date:
  • Size: 46.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ebus_sdk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d4a3adef3027371f7a66ae1709510ac42e01999b7ea510ddd14732df8c0bda8e
MD5 80261598e3d99acee07665025b96b7dc
BLAKE2b-256 bb847398107af83c073b03365bfc4dba35d7d35c182d1e2ea3b70942019822a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for ebus_sdk-0.2.0.tar.gz:

Publisher: publish.yml on electrification-bus/python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ebus_sdk-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ebus_sdk-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 29.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ebus_sdk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e56f19163fe92bc8ba16c876e0e13e392722a0e621f803735a8bdfe4c1cf362a
MD5 08c7b5cd3be1a0cd0cdd891a640d40c7
BLAKE2b-256 dd77148177bc609706eba43f374a6ab9f587b749c70cb55871e01195e6d2908a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ebus_sdk-0.2.0-py3-none-any.whl:

Publisher: publish.yml on electrification-bus/python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page