Skip to main content

earn-e-p1

Async Python library for communicating with EARN-E P1 energy meters via UDP.

The EARN-E P1 meter reads a smart meter's P1 port and broadcasts real-time energy data via UDP on the local network. This library listens for those broadcasts and provides parsed device data.

Installation

pip install earn-e-p1

Usage

Persistent listener

For long-running applications (e.g., Home Assistant integrations) that need continuous updates:

import asyncio
from earn_e_p1 import EarnEP1Listener, EarnEP1Device

def on_update(device: EarnEP1Device, raw: dict) -> None:
    print(f"Power: {device.data.get('power_delivered')} kW")
    print(f"Serial: {device.serial}")

async def main() -> None:
    listener = EarnEP1Listener()
    listener.register("192.168.1.100", callback=on_update)
    await listener.start()

    try:
        await asyncio.sleep(3600)  # listen for 1 hour
    finally:
        await listener.stop()

asyncio.run(main())

The listener supports multiple devices — call register() for each device IP. Packets are demultiplexed by source IP and each device maintains its own merged state.

Discover devices

Find EARN-E devices on the network:

from earn_e_p1 import discover

devices = await discover(timeout=10)
for device in devices:
    print(f"Found {device.host} (serial: {device.serial})")

Validate a specific host

Check if a specific IP is an EARN-E device:

from earn_e_p1 import validate

device = await validate("192.168.1.100", timeout=10)
if device:
    print(f"Confirmed: {device.serial}")

Discover/validate while a listener is running

If a listener is already active, use the instance methods to avoid port conflicts:

# Discover using the active socket
devices = await listener.discover(timeout=10)

# Validate using the active socket
device = await listener.validate("192.168.1.100", timeout=10)

Data Model

The callback receives two arguments:

  • device (EarnEP1Device) — accumulated device state with merged data from all packets
  • raw (dict) — the raw packet as received
@dataclass
class EarnEP1Device:
    host: str                          # Device IP address
    serial: str | None = None          # Serial number (set once from first full telegram)
    model: str | None = None           # Device model
    sw_version: str | None = None      # Firmware version
    data: dict[str, Any] = field(...)  # Merged sensor data from all packets
    seen_packet_types: set[PacketType] = field(...)  # Packet types seen so far

The device sends two types of UDP broadcasts:

Type Keys Frequency
Realtime power_delivered, power_returned, voltage_l1, current_l1 (plus voltage_l2/l3, current_l2/l3 on 3-phase meters) ~1s
Full telegram energy_delivered_tariff1/2, energy_returned_tariff1/2, gas_delivered, wifiRSSI, serial, model, swVersion ~1min

The library merges all packets into device.data, so it always contains the latest value for every key.

Each type always carries every key the meter supports, so a 1-phase meter never sends voltage_l2/voltage_l3 and an electricity-only meter never sends gas_delivered. device.data_complete becomes True once a packet of every type has been seen. From then on device.data holds the meter's complete key set, and any key still missing is one this meter does not report.

License

MIT

Release files for earn-e-p1 0.3.0

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

Source distribution (sdist)

Source distribution for earn-e-p1 0.3.0
File Size Uploaded
earn_e_p1-0.3.0.tar.gz 21.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for earn-e-p1 0.3.0
File Interpreter ABI Platform
earn_e_p1-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 28.9 kB

Release files / earn_e_p1-0.3.0.tar.gz

Download URL earn_e_p1-0.3.0.tar.gz
Size 21.4 kB
Tags Source
SHA-256 checksum
How to use checksums
cbf158067f7aa9ffb4faf0a3f38f1aac8df6ba27edaa565463b2a70189ebc98e
BLAKE2b-256 checksum
How to use checksums
6f88205d116e4ecc1baa2c8ce4c2cf94ad02de758107fac648bbae522235b6cb
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 / earn_e_p1-0.3.0-py3-none-any.whl

Download URL earn_e_p1-0.3.0-py3-none-any.whl
Size 7.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
40ca32edd1cd6b5570dee53012056e66ed58bcf0252e7cb951264d72e8f93f0c
BLAKE2b-256 checksum
How to use checksums
2bb6e8c58eb12fbd46df65927a5627c657286106593ccdb97218c95fb60754de
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

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.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