Skip to main content

HART-IP protocol library for Python

Project description

hartip-py

CI PyPI Python License Code style: ruff

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.2.0.tar.gz (96.0 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.2.0-py3-none-any.whl (59.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: hartip_py-0.2.0.tar.gz
  • Upload date:
  • Size: 96.0 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.2.0.tar.gz
Algorithm Hash digest
SHA256 dbcc138a1766434da13b756e691732cc5a69a42671208f56f1571206f70ace0b
MD5 292f9cd8e8e0c0e4734d88a44102979e
BLAKE2b-256 dbf96153a41defaaab33ec0cf3c4be9d8243ac625d573d8e9945b9d12c26806f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: hartip_py-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 59.8 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93ad1c835ef502c67a1f400ced7a0f90f5bb87a5ef4967818ac935304f8e921c
MD5 80c19395ef14730d6c1850bf4146b9fc
BLAKE2b-256 8e53c5b8e32c9b6b718a8bd4ad46235c06432d00fcc7ecd579d6d691b4b0eeb9

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