Skip to main content

Pychonet

GitHub Release License Project Maintenance

A Python library for interfacing with the ECHONET Lite protocol as commonly used in Japan. Useful for interfacing with HVACs, lighting systems, electric car chargers, solar systems, distribution panel meters, water heaters, and many other devices that support ECHONET Lite.

Designed to work with Python 3.9+. Built on asyncio for compatibility with Home Assistant and other async frameworks.

Installation

pip install pychonet

Basic Usage

Start the ECHONET Lite listener

import asyncio
from pychonet.lib.udpserver import UDPServer
from pychonet import ECHONETAPIClient as api

udp = UDPServer()
loop = asyncio.get_event_loop()
udp.run("0.0.0.0", 3610, loop=loop)
server = api(server=udp)

Configure the client

import logging
_LOGGER = logging.getLogger(__name__)

server.configure(
    message_timeout=50,       # 50 ticks × 0.1s = 5s per request (default: 200 = 20s)
    logger=_LOGGER.debug,     # route pychonet logs to your logger
    debug=True,               # enable verbose internal logging
    discover_callback=my_cb,  # async callback when unknown host is detected
)

Discover devices

# Discover instances on a host
await server.discover('192.168.1.6')

# Register multicast for the interface used to reach a host
server.register_multicast('192.168.1.6')

Pre-populate instance state (without network discovery)

Useful when restoring known device state from stored configuration:

server.register_instance(
    host='192.168.1.6',
    eojgc=1, eojcc=48, eojci=1,
    ntfmap=[0x80, 0x81, 0x88],   # STATMAP — EPCs the device pushes notifications for
    setmap=[0x80, 0x81, 0xB3],   # SETMAP
    getmap=[0x80, 0x81, 0x88, 0xB3, 0xBB],  # GETMAP
    uid='abc123',
)

Unregister a host (e.g. on shutdown)

server.unregister_host('192.168.1.6')

Create a device instance

from pychonet import Factory

# Using the Factory (recommended — selects the correct class automatically)
device = Factory('192.168.1.6', server, 1, 48, 1)

# Or directly
from pychonet import HomeAirConditioner
aircon = HomeAirConditioner('192.168.1.6', server)

Read EPC values

# Read all supported EPCs
data = await device.update()

# Read specific EPCs
data = await device.update([0x80, 0xBB, 0xB3])

# Read from local cache (no network request)
data = await device.update([0x80], no_request=True)

Write EPC values

# Set a single EPC
await device.setMessage(0x80, b'\x30')  # operating status = on

# Set multiple EPCs
await device.setMessages([
    {'EPC': 0x80, 'EDT': b'\x30'},
    {'EPC': 0xB3, 'EDT': b'\x41'},
])

Register custom EPC decode functions (quirks)

For devices with non-standard EPC behaviour, register instance-level overrides:

def my_custom_decoder(edt):
    return {'value': int.from_bytes(edt, 'big')}

device.register_epc_function(0xB3, my_custom_decoder)

This creates an instance-level override — the custom function only applies to this device instance, not all instances of the same device class.

Push notifications

Register a callback to receive unsolicited INF packets from the device:

async def on_update(isPush: bool):
    data = await device.update([0x80, 0x88], no_request=True)
    print(f"Device state changed: {data}")

server.register_async_update_callbacks('192.168.1.6', 1, 48, 1, on_update)

Unregister when done:

server.unregister_async_update_callbacks('192.168.1.6', 1, 48, 1)

Populate property maps

await server.getAllPropertyMaps('192.168.1.6', 1, 48, 1)

Return values from update()

Return value Meaning
dict Success — EPC values keyed by EPC code
None pychonet _waiting queue was busy — request not sent, serve cached data
Raises TimeoutError Request sent but device did not respond

None (queue busy) should be treated as a cache-serve rather than an error. A TimeoutError indicates the device genuinely did not respond within message_timeout ticks.

Device Classes

pychonet includes classes for many ECHONET Lite device types. Each class provides an EPC_FUNCTIONS dict mapping EPC codes to decode functions, and inherits the generic update() and setMessage() API from EchonetInstance.

Use Factory() to automatically select the correct class based on eojgc/eojcc:

from pychonet import Factory
device = Factory(host, server, eojgc, eojcc, eojci)

For device types not yet supported, EchonetInstance provides raw connectivity and the generic update()/setMessage() API works for any EPC.

Using with Home Assistant

For Home Assistant users there is a dedicated integration installable via HACS:

https://github.com/scottyphillips/echonetlite_homeassistant

Hall of Fame

Big thanks to Naoki Sawada (nao-pon) for many excellent updates including push notification support via multicast. どうもありがとうございます!

Thanks to Jason Nader for quality of life updates to the codebase and documentation.

Thanks to khcnz (Karl Chaffey) and gvs for helping refactor the old code and contributing to testing.

Thanks to Dick Swart, Masaki Tagawa, Paul, khcnz, Kolodnerd, Leonunix, and Alfie Gerner for contributing code updates to this library.

Thanks to Jeffro Carr who inspired me to write a native Python ECHONET library for Home Assistant.

Thanks to Futomi Hatano for open sourcing a well-documented ECHONET Lite library in Node JS: https://github.com/futomi/node-echonet-lite

Extra Special thanks to 'sayurin' for offering up so many constructive ideas on how to make this project better,

References

License

MIT License — refer to LICENSE for details.

Portions of 'ECHONET Lite Device Emulator' (Copyright 2020 Kanagawa Institute of Technology) have been used. Licensed under MIT.

The UDP code is based on 'aio-udp-server' (Copyright 2021 Dmitriy Bashkirtsev). Licensed under GPL: https://github.com/bashkirtsevich-llc/aioudp


Metadata

Release files for pychonet 2.8.1

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

Source distribution (sdist)

Source distribution for pychonet 2.8.1
File Size Uploaded
pychonet-2.8.1.tar.gz 135.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pychonet 2.8.1
File Interpreter ABI Platform
pychonet-2.8.1-py3-none-any.whl Python 3 none any Details

Total release size: 265.8 kB

Release files / pychonet-2.8.1.tar.gz

Download URL pychonet-2.8.1.tar.gz
Size 135.1 kB
Tags Source
SHA-256 checksum
How to use checksums
6b0891883af326d38e8ccb0e60e2d07781879eaccc993832739cae44b33bac28
BLAKE2b-256 checksum
How to use checksums
e86b0ae4ef0de49350ef89ae11fe3347b5a85e5ab177be56d5c12a45d994b0e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.5

Release files / pychonet-2.8.1-py3-none-any.whl

Download URL pychonet-2.8.1-py3-none-any.whl
Size 130.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cfdd904722389fe22accf05e9f3bb8ecf6d2244a722bc6d4fe8e124b9ceffc52
BLAKE2b-256 checksum
How to use checksums
80b1ed7cc4947065afcd66fa36b21bde3f96d9cce4b310151d70a79c0576a4bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.5

Release history Release notifications | RSS feed

2.8.2

1 release file

This release

2.8.1 This release

2 release files

2.8.0

2 release files

2.7.14

2 release files

2.7.13

2 release files

2.7.12

2 release files

2.7.11

2 release files

2.7.10

2 release files

2.7.9

2 release files

2.7.8

2 release files

2.7.7

2 release files

2.7.6

2 release files

2.7.5

2 release files

2.7.4

2 release files

2.7.3

2 release files

2.7.2

2 release files

2.7.1

2 release files

2.7.0

1 release file

2.6.17

2 release files

2.6.16

2 release files

2.6.15

2 release files

2.6.12

2 release files

2.6.11

2 release files

2.6.9

2 release files

2.6.8

2 release files

2.6.7

2 release files

2.6.6

2 release files

2.6.5

2 release files

2.6.4

2 release files

2.6.3

2 release files

2.6.2

2 release files

2.6.1

2 release files

2.6.0

2 release files

2.5.2

2 release files

2.5.1

2 release files

2.5.0

2 release files

2.4.2

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.18

2 release files

2.3.13

2 release files

2.3.10

2 release files

2.3.9

2 release files

2.3.8

2 release files

2.3.7

2 release files

2.3.6

2 release files

2.3.5

2 release files

2.3.4

2 release files

2.3.3

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.7

2 release files

2.1.6

2 release files

2.1.5

2 release files

2.1.4

2 release files

2.1.3

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.23

2 release files

2.0.20

2 release files

2.0.19

2 release files

2.0.18

2 release files

2.0.17

2 release files

2.0.16

2 release files

2.0.15

2 release files

2.0.14

2 release files

2.0.13

2 release files

2.0.9

2 release files

2.0.8

2 release files

2.0.7

2 release files

2.0.6

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.10

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0

3 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