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).
pip install hartip-pyOnly dependency: construct for binary parsing.
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})")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()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 failureException hierarchy:
HARTError
├── HARTIPError
│ ├── HARTIPTimeoutError
│ ├── HARTIPConnectionError
│ │ └── HARTIPTLSError
│ └── HARTIPStatusError
└── HARTProtocolError
├── HARTChecksumError
├── HARTResponseError
└── HARTCommunicationError
| 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 |
# Unit tests (no server needed)
pytest
# Integration tests (requires HART-IP server)
pytest -m integrationIf you find this project useful, consider supporting development:
Dual-licensed under GPL-3.0 and a commercial license.
Free for open source use under GPL-3.0. If you want to use hartip-py in proprietary products without GPL obligations, a commercial license is available — see LICENSE-COMMERCIAL.md for details.