Skip to content

HL7 routing

Messages arriving on the HL7 port can go on to other systems: patient updates to the PACS and an AI vendor, orders to a VNA, results to a reporting system. Configuration › HL7 routing.

A route takes messages by:

  • type: ADT^A08, ADT^A0*, ORU (every event), *; empty means every type;
  • sending application and facility (MSH-3, MSH-4);
  • conditions on fields, all of which must hold.

Every route that takes a message sends its own copy, so one message can go to several systems, each edited its own way.

Path Means
PV1-2 A field
PID-3.4 A component
PID-3.4.1 A subcomponent
PID-3[2] The second repetition (the first by default)
OBX-5[*] Every repetition

A path names the field in every segment with that ID (every OBX, say); a condition holds when any of them matches.

Edits apply in order:

Action Does
Set Sets the value; it may name other fields: {PID-3.1}^^^{MSH-4}.
Set if empty Sets it only when it is empty.
Clear Empties it.
Prefix, Suffix Adds text before or after.
Replace Regular expression replace: pattern → value.
Map Translates the value through a lookup table.
Remove segment Removes every segment with the ID given as the path (ZPD).

Lookup tables translate codes: a value found in the table (any case) becomes the table’s; others keep theirs, or take the table’s default. Paste two columns from a spreadsheet to fill one.

Then, optionally, a script:

if (message.get('PV1-2') === 'E') reject('Emergency patients go by the ED feed');
message.set('PID-3.4', 'HOSP');
message.add('ZRT|' + message.type);

message.type, message.get(path[, n]), message.set(path, value[, n]) (every segment with the ID, or the nth), message.count(segment), message.remove(segment[, n]), message.add('ZXX|...'), message.toString(); reject(reason) keeps the message from the route’s destinations; log(...).

Test runs a sample message through the saved routes, and shows which take it and the copy each would send.

Reached over MLLP, optionally TLS. Each node queues every copy on its disk before it acknowledges the sender, and sends a destination’s queue one message at a time, in the order received, each once the one before was acknowledged.

Answer What happens
AA, CA Sent.
AR, CR, no answer, no connection Tried again after 5 seconds, doubling up to 10 minutes, holding the messages behind it. Alerted after 15 minutes.
AE, CE The queue stops there, with an alert, until someone retries the message (after fixing the cause) or skips it.

A destination can instead be set to put refused messages aside and go on. A stopped queue stays stopped across restarts. Messages keep their order per node: an interface keeps its MLLP connection on one node.

  • AA once the worklist has the message (when it takes it) and every copy is queued.
  • AE for a message that cannot be read, or that the worklist cannot use and no route takes.
  • AR (resend later) when the central service cannot be reached for the worklist, or a copy could not be stored.
  • Senders in enhanced mode (MSH-15 given) get CA, CE and CR.

A message the sender resends after an answer was lost may be delivered twice.

Every message received, searchable by patient ID, name, accession or control ID, by type, problems only, or destination, with each destination’s state: queued, sent, retrying, stopped, put aside, not sent (script), or failed. Open one to see it as received and as sent to each destination. Each node’s queues are shown above, with Retry now and Skip. Administrators with the history role can send messages again, as last sent or as received.

Messages are kept centrally, compressed, for Keep HL7 messages (default 90 days). They name patients: the list is for history users, and every look is audited.