Skip to main content

HART-IP protocol library for Python

Project description

hartip-py

CI PyPI Python License Code style: ruff DCO

Pure-Python HART-IP client library. Server functionality is not included.

Supports HART-IP v1 (plaintext, TCP/UDP) and v2 (TLS, Direct PDU, Audit Log).

Install

pip install hartip-py

Only dependency: construct for binary parsing.

Quick start

from hartip import HARTIPClient, parse_cmd0, parse_cmd1

# v1 over UDP (default)
with HARTIPClient("192.168.1.100") as client:
    resp = client.read_unique_id()
    info = parse_cmd0(resp.payload)
    print(info.manufacturer_name, info.device_id)

    resp = client.read_primary_variable()
    pv = parse_cmd1(resp.payload)
    print(f"{pv.value} (unit {pv.unit_code})")

TLS (HART-IP v2)

from hartip import HARTIPClient, HARTIP_V2_PSK_CIPHERS

# PSK authentication
with HARTIPClient(
    "192.168.1.100",
    protocol="tcp",
    version=2,
    psk_identity="client1",
    psk_key=b"\x00" * 16,
    ciphers=HARTIP_V2_PSK_CIPHERS,
) as client:
    resp = client.read_unique_id()

# CA-verified + mutual TLS
with HARTIPClient(
    "192.168.1.100",
    protocol="tcp",
    version=2,
    ca_certs="/path/to/ca.pem",
    certfile="/path/to/client.pem",
    keyfile="/path/to/client.key",
) as client:
    resp = client.read_unique_id()

# Custom certificate validation callback
def pin_cert(cert_dict):
    subject = dict(x[0] for x in cert_dict.get("subject", ()))
    return subject.get("commonName") == "my-device.local"

with HARTIPClient(
    "192.168.1.100",
    protocol="tcp",
    version=2,
    cert_validator=pin_cert,
) as client:
    resp = client.read_unique_id()

# Full custom SSLContext
import ssl
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_verify_locations("/path/to/ca.pem")

with HARTIPClient("192.168.1.100", protocol="tcp", version=2, ssl_context=ctx) as client:
    resp = client.read_unique_id()

Error handling

from hartip import HARTIPClient
from hartip.exceptions import (
    HARTIPConnectionError,
    HARTIPTimeoutError,
    HARTIPTLSError,
    HARTResponseError,
)

with HARTIPClient("192.168.1.100") as client:
    resp = client.read_unique_id()

    # Check manually
    if not resp.success:
        print(resp.error_message)

    # Or raise
    resp.raise_for_error()  # raises HARTResponseError on failure

Exception hierarchy:

HARTError
├── HARTIPError
│   ├── HARTIPTimeoutError
│   ├── HARTIPConnectionError
│   │   └── HARTIPTLSError
│   └── HARTIPStatusError
└── HARTProtocolError
    ├── HARTChecksumError
    ├── HARTResponseError
    └── HARTCommunicationError

Convenience methods

Method HART Command
read_unique_id() 0
read_primary_variable() 1
read_current_and_percent() 2
read_dynamic_variables() 3
read_tag_descriptor_date() 13
read_output_info() 15
read_long_tag() 20
read_additional_status() 48
send_command(cmd, ...) any
send_direct_pdu(commands) v2 Direct PDU
read_audit_log() v2 Audit Log

Testing

# Unit tests (no server needed)
pytest

# Integration tests (requires HART-IP server)
pytest -m integration

Support

If you find this project useful, consider supporting development:

Ko-fi

License

GPL-3.0-only

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

hartip_py-0.3.0.tar.gz (120.4 kB view details)

Uploaded Source

Built Distribution

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

hartip_py-0.3.0-py3-none-any.whl (73.1 kB view details)

Uploaded Python 3

File details

Details for the file hartip_py-0.3.0.tar.gz.

File metadata

  • Download URL: hartip_py-0.3.0.tar.gz
  • Upload date:
  • Size: 120.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for hartip_py-0.3.0.tar.gz
Algorithm Hash digest
SHA256 125083459fb4b4322979f4d05de93208c3d6664f29da1a459a6d807ec3e619f6
MD5 2dc042b50b01f44e2425b192d96cc47a
BLAKE2b-256 b4cac02a9feb9ab46067817934f9755e08fb531aa36233bddfd08e6177803c4a

See more details on using hashes here.

File details

Details for the file hartip_py-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: hartip_py-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 73.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for hartip_py-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 14e40c93e2e38b88a6a962f0c67ac8d57702d3b59cdec905ed04606e7f1dc880
MD5 ce5e9a378d2702ae1bcecd01a39e52c9
BLAKE2b-256 d0150afc0221a9eacc4103866ab639355f7d60845bbff5c3b23bbc6bdab23e1b

See more details on using hashes here.

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