Repository navigation
Getting started
Python 3.10 or newer:
pip install hart-sim
hart-sim --versionhart-sim 0.1.2
Save this as plant.yaml:
devices:
- {profile: pressure, polling_address: 1, device_id: 0x000001, tag: PT-101}
- {profile: temperature, polling_address: 2, device_id: 0x000002, tag: TT-201}hart-sim serve --bench plant.yamlhart-sim: 2 devices on HART-IP 127.0.0.1:5094 (tcp+udp), control on 127.0.0.1:5095
Leave it running and use a second terminal. For a single device, hart-sim serve pressure is enough.
The image runs the same two devices without a local Python, with no bench file needed:
docker run --rm --name sim -p 5094:5094 -p 5094:5094/udp -p 127.0.0.1:5095:5095 ghcr.io/steitec/hart-simThe commands below work against it as they are if hart-sim is installed. Without it, run them inside the
container, for example docker exec sim hart-sim poll. The control channel has no authentication, hence 127.0.0.1:
in front of it. For CI, see Testing in CI.
$ hart-sim poll
addr 1 PT-101 pressure-transmitter id 0x000001
addr 2 TT-201 temperature-transmitter id 0x000002
$ hart-sim cmd --tag PT-101 3
loop 10.70 mA | PV 418.9 kPa | SV 23.5 degChart-sim poll finds the devices with commands 0 and 13, and hart-sim cmd sends one command. The output is
decoded for commands 1, 2, 3, 13, 15 and 48, and every other command prints the response code, the status and
the data as hex. Add --udp for UDP.
$ hart-sim inject PT-101 sensor_failure
$ hart-sim cmd --tag PT-101 3
status: device malfunction, more status available, PV out of limits | loop 21.00 mA | PV 416.9 kPa (bad) | SV 23.5 degC
$ hart-sim clear PT-101The loop current goes to the NE 43 high alarm of 21 mA, and command 48 has the details.
The package has a small HART-IP master, which also works on its own against real gateways:
from hart_sim.client import HartIPClient
with HartIPClient("127.0.0.1") as client: # transport="udp" for UDP
device = client.find("PT-101") # command 11, broadcast by tag
variables = device.read_variables() # command 3
print(f"{variables.pv:.1f} kPa, {variables.current_ma:.2f} mA")
print(device.write_range(0, 600)) # command 35; 0 means acceptedNext: Device profiles, Testing in CI or Fault injection recipes.
hart-sim · MIT licensed · HART is a trademark of the FieldComm Group; hart-sim is not affiliated with it.