NOTE This is not documentation for any existing Inbound Interfaces. None of this applies if a site is not already using the configurable parser or if they are not using a Single DB (separate Touch and EMR databases).
Why do we need a configurable parser?
Our approach to inbound interfaces was not extensible and requires too much developer intervention. We have a default HL7Parser that provides basic HL7 parsing and processing, and if customers need something different a developer creates a new sub-class of the HL7Parser to handle the differences. We would then need to build the new code, deploy the new code, and update the local Touch Interface Service Web.config XML to use the new parser.
The goal with the new configurable HL7 parser was to come up with an approach that would be able to handle the typical customizations without code changes.
What has changed?
Here are the changes that were made:
- Most Touch Inbound Interface settings (e.g. "ParserType", "ProcessVisitFromSIU", etc) can now be set in the database. Previously parser information needed to be defined in the Touch Interface Service's Web.config. The new settings are stored in the EMR.SvrSettings table.
- Updated base HL7Parser with common functionality that was repeatedly re-implemented for multiple clients
- Created new ConfigurableHL7Parser that allows users more control over HL7 parsing via new settings.
The ConfigurableHL7Parser
A new ConfigurableHL7Parser has been added that allows users more control over HL7 parsing via new settings.
The ConfigurableHL7Parser can be selected by using "configurable" as the Parser Type.
New Settings
This section lists out the new settings. The tables below will give you setting names in the database, the data format, and more details. If you notice a value in "Web.config Setting Name" section that is a configuration that can be set locally or in the database. If a value is set in both the database and the local config the value in the database will be used.
New Settings to control HL7 Parser Behavior
These settings are used to control overall behavior of the parser. For example, we can control whether or not Patient Visits should be created from SIU messages.
|
DB Setting Name |
Web.conf Setting Name |
Setting Type |
Default Value |
Description |
|
inbound-ParserType-str |
ParserType |
string |
|
HL7 Parser Name. Must be a valid parser name. If no value is specified then the default HL7 parser will be used. Set value to "configurable" to use the ConfigurableHL7Parser. |
|
inbound-CCDAParserType-str |
CCDAParserType |
string |
|
CCDA Parser Name. Must be a valid parser name. If no value is specified then the default CCDA parser will be used |
|
inbound-FacilityName-str |
FacilityName |
string |
|
Facility Name |
|
inbound-TimeZone-str |
TimeZone |
string |
|
Time Zone ID string |
|
inbound-TimeZoneOffset-int |
TimeZoneOffset |
integer |
|
Time Zone Offset from East Coast Time. Can be negative |
|
inbound-ProcessVisitFromADT-bool |
ProcessVisitFromADT |
boolean |
TRUE |
Create Patient Visits from ADT messages |
|
inbound-ProcessVisitFromADT-hl7 |
|
string - HL7 terser spec |
|
Used in addition to the ProcessVisitFromADT setting. This specifies the segment or field that we want to check against a whitelist. If ProcessVisitFromADT is true and the field value matches the whitelist then the parser will process visits from ADT |
|
inbound-ProcessVisitFromADT-whitelist |
|
string - whitelist |
|
Whitelist for fields found for inbound-ProcessVisitFromADT-hl7 |
|
inbound-SaveADTForPreopImport-bool |
SaveADTForPreopImport |
boolean |
FALSE |
Save ADT message for Preop import |
|
inbound-AllowOutOfOrderSIU-bool |
AllowOutOfOrderSIU |
boolean |
FALSE |
Allow out of order processing of SIU messages |
|
inbound-ProcessVisitFromSIU-bool |
ProcessVisitFromSIU |
boolean |
TRUE |
Create Patient Visits from SIU messages |
|
inbound-shouldProcessSIU-hl7 |
|
string - HL7 terser spec |
|
If SIU message’s started time is in the future then this specifies the segment or field that we want to check against a whitelist. If field value matches the whitelist then the parser will process the SIU message |
|
inbound-shouldProcessSIU-whitelist |
|
string - whitelist |
|
Whitelist for fields found for inbound-shouldProcessSIU-hl7 |
|
inbound-UpdatePatientFromSIU-bool |
UpdatePatientFromSIU |
boolean |
|
Update Patient info from SIU message |
|
inbound-updateHeightWeight-bool |
|
boolean |
FALSE |
Update Patient Height and Weight from ADT |
|
inbound-processAllergies-bool |
|
boolean |
FALSE |
Process Allergies from ADT |
|
inbound-ProcessSwapBed-bool |
|
boolean |
FALSE |
Process Swap Bed |
|
inbound-ForwardMessages-bool |
ForwardMessages |
boolean |
FALSE |
Should messages be forwarded or not |
|
inbound-ForwardDemo-bool |
ForwardDemo |
boolean |
FALSE |
Should demo messages be forwarded |
|
inbound-ForwardDestination-str |
ForwardDestination |
string - HL7 terser spec |
|
Name of OutboundDestination to forward messages to |
|
inbound-UseLocationExtractionStrategy-bool |
UseLocationExtractionStrategy |
boolean |
FALSE |
Use Location Extraction Strategy while parsing PDF files |
|
inbound-UsePclPrinterDriver-bool |
UsePclPrinterDriver |
boolean |
FALSE |
Use PCL Printer Driver |
|
inbound-canProcessVitalSigns-bool |
|
boolean |
FALSE |
Process Vital Signs. NOTE: There is no default implementation for parsing vital signs. Only LakeNormanHL7Parser implements this. |
|
inbound-canProcessVitalSigns-hl7 |
|
string - HL7 terser spec |
|
If canProcessVitalSigns is true then this specifies the segment or field that we want to check against a whitelist. If field value matches the whitelist then the parser will process the vital signs |
|
inbound-canProcessVitalSigns-whitelist |
|
string - whitelist |
|
Whitelist for fields found for inbound-canProcessVitalSigns-hl7 |
New Settings to Control HL7 Data Mapping
We have a variety of data points that are extracted from HL7 messages. We have added the ability to configure which HL7 fields are used to populate that date. The following settings show which fields are available.
|
DB Setting Name |
Setting Type |
Default Value |
Description |
|
inbound-mrn-hl7 |
string - HL7 terser spec |
|
MRN field |
|
inbound-mrnPidField-int |
integer |
3 |
If custom MRN field is not set then MRN will be obtained from the PID field of ADT message. This is the index in the PID field that should be used as the MRN. |
|
inbound-siuMrnPidField-int |
integer |
3 |
If custom MRN field is not set then MRN will be obtained from the PID field of SIU message. This is the index in the PID field that should be used as the MRN. |
|
inbound-accountNumber-hl7 |
string - HL7 terser spec |
|
Account number field |
|
inbound-alternativeID-hl7 |
string - HL7 terser spec |
|
Alternative ID field |
|
inbound-fillerAppointmentID-hl7 |
string - HL7 terser spec |
|
Filler Appointment ID field |
|
inbound-anesthesiaProvider-hl7 |
string - HL7 terser spec |
|
Anesthesia Provider field |
|
inbound-attendingDoctor-hl7 |
string - HL7 terser spec |
|
Attending Doctor field |
|
inbound-started-hl7 |
string - HL7 terser spec |
|
Appointment started time |
|
inbound-ended-hl7 |
string - HL7 terser spec |
|
Appointment ended time |
|
inbound-duration-hl7 |
string - HL7 terser spec |
|
Appointment duration field |
|
inbound-durationUnit-hl7 |
string - HL7 terser spec |
|
Appointment duration unit field |
|
inbound-procedure-hl7 |
string - HL7 terser spec |
|
Procedure field |
|
inbound-procedures-hl7 |
string - HL7 terser spec |
|
Procedures field - use this if you want to support multiple procedures |
|
inbound-diagnoses-hl7 |
string - HL7 terser spec |
|
Diagnoses field - if there are multiple values the first one will be returned |
|
inbound-location-hl7 |
string - HL7 terser spec |
|
Location field |
|
inbound-labAbnormalFlag-hl7 |
string - HL7 terser spec |
|
Lab Abnormal Flag field |
|
inbound-labOrderAbbrev-hl7 |
string - HL7 terser spec |
|
Lab Order Abbreviation field |
|
inbound-labOrderCode-hl7 |
string - HL7 terser spec |
|
Lab Order Code field |
|
inbound-labOrderID-hl7 |
string - HL7 terser spec |
|
Lab Order ID field |
|
inbound-labOrderName-hl7 |
string - HL7 terser spec |
|
Lab Order Name field |
|
inbound-labResultAbbrev-hl7 |
string - HL7 terser spec |
|
Lab Result Abbreviation field |
|
inbound-labResultCode-hl7 |
string - HL7 terser spec |
|
Lab Result Code field |
|
inbound-labResultName-hl7 |
string - HL7 terser spec |
|
Lab Result Name field |
|
inbound-labResultValue-hl7 |
string - HL7 terser spec |
|
Lab Result Value field |
|
inbound-patientEmail-hl7 |
string - HL7 terser spec |
|
Patient Email field |
|
inbound-phone1-hl7 |
string - HL7 terser spec |
|
Phone 1 field |
|
inbound-phone2-hl7 |
string - HL7 terser spec |
|
Phone 2 field |
|
inbound-languageField-hl7 |
string - HL7 terser spec |
|
Language field |
Tersers and Whitelists
The above tables refer to "HL7 terser spec" and "whitelist" strings. This section will go into details of what that means.
A Terser is an HL7 parser that provides users with a concise way to specify which HL7 data to retrieve. This is done via a Terser Specification. In the above table when you see a data type of "string - HL7 terser spec" that means a Terser Specification string is the expected value for that setting.
Whitelists can be used in conjunction with HL7 Terser Specifications. The configurable parser can extract values from the HL7 message based on the Terser Specification and check those values against a whitelist. The whitelist matching supports exact matches, or a simple 'starts with' match.Example whitelist string.
Terser Specifications
We will use the following HL7 message to illustrate how the Terser works:
MSH|^~\&|CWS|SIP|||201906051649||SIU^S12|117007299|P|2.4|||AL|NE||||||
EVN|S12|201906051649||BOOK|ACY7813^Bluth^June^C^^^^^^^^^XX|||
SCH|V1-B20190605164945773|E0-B20190605164402873||||BOOK|MRI L-Spine WO W/IVCS -72148/J3010/J2250|IVMRILSWO^MRI L-Spine WO W/IVCS -72148/J3010/J2250|120|min|^^^201906201300|||||||||ACY7813^Bluth^June^C^^^^^^^^^XX||||||||
PID|1||M438400^^^001||DOE^JANE^ANN^^^^L||19700206|F||WH|313 Main St^^HOUSTON^TX^12345||555-555-1234|||D|METH|V00300342557^^^001|267-83-7354|||HIS|||||||||||||||||
PV1|1|O|CCIR||||MENRG^Johnson^Garry^G^Jr.^Dr^MD^^^^^^XX|||||||||||SDC||CARE|||||||||||||||||||SIP||SCH|||201906201200||||||||OISEI^Smith^Matt^^^^MD^^^^^^XX|
ROL|1|AD|PP|OISEI^Smith^Seijo^^^^MD^^^^^^XX|||||||||
ROL|2|AD|FHCP|OISEI^Smith^Seijo^^^^MD^^^^^^XX|||||||||
ROL|3|AD|AT|MENRG^Johnson^Garry^G^Jr.^Dr^MD^^^^^^XX|||||||||
RGS|1||ANES01^CCIR^Cardiac Cath/Intervention Rad|
RGS|2||ANES01^SURG^Surgery Anes|
RGS|3||CCIRRN^CCIR^Cardiac Cath/Intervention Rad|
RGS|4||XRMRI01^CCIR^Cardiac Cath/Intervention Rad|
RGS|5||XRMRI01^MRI^Magnetic Resonance Imaging|
AIS|1||ANES01|201906201300|||120|min||Booked|||
AIS|2||CCIRRN|201906201300|||120|min||Booked|||
AIS|3||XRMRI01|201906201300|||120|min||Booked|||
AIL|1||^RAD|Outpatient|||||||||
AIP|1|A|MENRG^Johnson^Garry^G^Jr.^Dr^MD^^^^^^XX|Doctor|||||||||
The Terser has support for concatenating values. Using a "+" symbol in between two values indicates that you want the result to be the concatenation of the two values specified. You can concatenate more than 2 values.
A Terser Specification is a text string that tells the ConfigurableHL7Parser which HL7 field it should use.
For example, the inbound-mrn-hl7 setting can be used to tell the ConfigurableHL7Parser which field in the HL7 message should be used as the MRN. Using the above HL7 message, If the inbound-mrn-hl7 setting was set to "PID-3-1" then the value "M438400" would be extracted and used as the MRN.
Here are some example Terser Spec Strings along with values that would be extracted from the above HL7 message.
Terser Specification String Format
The Terser Spec string is formatted as follows:
<segment_name>"["<segment_index>"]""-"<field_index>"-"<sub_field_index>
Non-repeating Segments
To extract a non-repeating segment you can use Terser Spec strings like:
PID-3 - will return PID segment, field 3
PID-3-1 - will return PID segment, field 3, sub-field 1
Here are some Terser Spec strings and data that would be extracted from our example HL7 message:
Terser Spec String = "PID-3" will return "M438400^^^001"
Terser Spec String = "PID-3-1" will return "M438400"
Terser Spec String = "PID-3-2" will return ""
Terser Spec String = "PID-3-4" will return "001"
Repeating Segments
To extract a repeating segment you can use Terser Spec strings like:
AIS-3 - will return all values of AIS segment, field 3
AIS[*]-3 - will return all values of AIS segment, field 3
AIS[2]-3 - will return the value of AIS segment 2, field 3
Here are some Terser Spec strings and data that would be extracted from our example HL7 message:
Terser Spec String = "AIS-3" will return "ANES01", "CCIRRN", "XRMRI01"
Terser Spec String = "AIS[*]-3" will return "ANES01", "CCIRRN", "XRMRI01"
Terser Spec String = "AIS[2]-3" will return "CCIRRN"
NOTE - whether or not all values are used will depend on the data point you are attempting to extract. If the data point can accept multiple values it will take all the values. If the data point accepts a single value the first one will be picked.
Concatenating Fields
The Terser has support for concatenating values. Using a "+" symbol in between two values indicates that you want the result to be the concatenation of the two values specified. You can concatenate more than 2 values.
PID-3-1+PV1-3 - will return PID segment, field 3, sub-field 1
+
PV1 segment, field 3
Here are some Terser Spec strings and data that would be extracted from our example HL7 message:
Terser Spec String = "PID-3-1+PV1-3" will return "M438400CCIR"
Terser Spec String = "PID-3-1+AIS[2]-3" will return "M438400CCIRRN"
Terser Spec String = "PID-3-1+RGS[2]-3-2" will return "M438400SURG"
Specifying Default or Fallback Fields
The Terser has support default or fallback values. Using a "|" symbol in between two values indicates that you want to try and use the first value, but if it doesn't exist then the second value should be used. You can think of it kind of like an "or". Use value 1 or value 2. You can fallback between more than 2 values.
PID-3-1|PV1-3 - will return PID segment, field 3, sub-field 1
if PID-3-1 does not exist
PV1 segment, field 3
Here are some Terser Spec strings and data that would be extracted from our example HL7 message:
Terser Spec String = "PID-3-1|NOTEXIST1-1-1|NOTEXIST2-1-1" will return "M438400"
Terser Spec String = "NOTEXIST1-1-1|PID-3-1|NOTEXIST2-1-1" will return "M438400"
Terser Spec String = "NOTEXIST1-1-1|NOTEXIST2-1-1|PID-3-1" will return "M438400"
NOTE - You cannot have both "|" and "+" in the same Terser Specification string.
Whitelists
Whitelists can be used in conjunction with HL7 Terser Specifications. The configurable parser can extract data points from the HL7 message based on the Terser Specification and check those values against a Whitelist. The Whitelist matching supports exact matches, or a simple 'starts with' match.
Example whitelist string:
SURG1, SURG2, OR*
With the above example string the whitelist match will return true if any of the extracted values match
SURG1, or SURG2, or starts with OR.
A common reason to use a Whitelist is to control the processing of ADT messages based on Location. Consider the following example configuration:
inbound-ProcessVisitFromADT-bool = "true"
inbound-ProcessVisitFromADT-hl7 = "PV1-3"
inbound-ProcessVisitFromADT-whitelist = "SURG1, CCIR, OR*"
If an ADT message came in and the settings were as above, we would attempt to process the ADT message since inbound-ProcessVisitFromADT-bool is true. Then because we have a Terser Specification set and a Whitelist set, we would extract the specified value from value from PV1-3 and check it against the whitelist.
If we were sent the our example HL7 message we would get the following results:
PV1-3 = "CCIR"
Since the PV1-3 value is "CCIR" and it is in the Whitelist we would process the message.
How to Configure the ConfigurableHL7Parser Settings
Settings are store in the EMR.SvrSettings table.
You can add a setting by running a SQL INSERT. The insert statement would look something like this:
INSERT INTO SvrSettings
(SvrSettingID, Name, Value, ModifiedBy, LastModified, StatusID)
VALUES
(10, 'inbound-mrn-hl7', 'PID-3-1', 'sidris', '2020-01-01 06:15:53.173', 1);
Make sure that the SvrSettingID that you use is unique.
The StatusID value of a SvrSetting controls whether or not the value is active. Set StatusID=1 to ensure that the newly added SvrSetting is active. If you want to disable a SvrSetting you can set StatusID=0.
NOTE - it is possible to have duplicate SvrSettings with the same Name. To avoid this do a query of the existing SvrSettings and update the existing value.
Comments
0 comments
Please sign in to leave a comment.