One of our trading partners is sending us clinical documents from their EHR system. These are plain text documents. The documents are being sent in HL7 v2.3 ORU^R01 messages.
They are sending us the document in a single OBX segment with line breaks in the OBX-5 field. I have seen other systems send each line in a separate OBX segment. I call that the "card punch" format, because each line of the report is on its own data card, just like the old days.
This is what one of the messages looks like:
MSH|^~\\&|DOC|K|DOC|WSUPG1|20110328082244||ORU^R01|Q1484927743T1489224997||2.3|||AL
PID|1|...
PV1|1|CD:123456||CD:9999|||0000000000^SMITH^ZACHARY|||...
ORC|RE||...
OBR|1||999999999|PROGN^Progress Note^^^xxx SICU Progress Note|||...
OBX|1|TX|PROGN^Progress Note||...NOTE GOES HERE~New Line~Another New Line||||||F|||20110328082242||
They are sending us the following document types (the left value is the code that I recieve, and the right side is the corresponding LOINC code):
DISCH^Discharge Summary ==> code="18842-5" displayName="DISCHARGE SUMMARIZATION NOTE"
PROGN^Progress Note ==> code="11506-3" displayName="Subsequent evaluation note"
HP^History and Physical ==> code="34117-2" displayName="History and Physical Note"
CONS^Consultation ==> code="11488-4" displayName="CONSULTATION NOTE"
OPRPT^Operative Report ==> code="11504-8" displayName="Surgical operation note"
ADMN^Admission Note ==> code="34862-9" displayName="Admission Evaluation Note"
The document type code appears in the OBR-4 field and the OBX-3 field. The project manager has me filtering out the H&P documents because they are not in scope for the first phase of the project. I added a filter to discard the H&P documents, and I will get to remove that later.
The only other interesting thing is that I have to look up the National Provider Identifier (NPI) for the providers in the PV1 segment. The remote system is sending us their provider ID, and we need the NPI to match on. So, I have a database look-up that retrieves the NPI and places that in the message. I am performing the look-up on the PV1-7 Attending Doctor, PV1-8 Referring Doctor and the PV1-9 Consulting Doctor fields. I then take whichever of these three fields has an NPI (and is therefore, one of our doctors) and place that value into PV1-7.
NextGen will match on PV1-7 and will place the document into the doctor's PAQ (Provider Approval Queue). The document was already signed by a doctor at the sending facility (unless it is a Progress Note, in which case it may be signed by a non-doctor), so our Doctor's are not really "approving" the document. This is just a way to ensure that our doctor's see the document.
NextGen will also add the document to the appropriate patient's chart.
We are doing some final testing on this interface before moving it into production.
Showing posts with label HIT interfaces. Show all posts
Showing posts with label HIT interfaces. Show all posts
Monday, March 28, 2011
Friday, December 17, 2010
Radiology Orders and Results Interface
Here is another interesting interface project.
We want to send Radiology Orders from our EHR system to our trading partner and want the Radiology Results document to be returned electronically and placed into the patient's chart in the EHR.
Simple. Right.
Except, the scheduling system at our trading partner will not receive the order. I suggested that we send them an order message (ORM), a scheduled appointment (SIU), and a registration message for a future encounter (ADT). They told us that they could not process any of those HL7 messages into their scheduling system. So, we settled on this kluge. I will convert the order message into an email that I will send securely to the scheduling department. They will then manually key the appointment into their system. Hopefully, they will remember to key our Order Number so that I can match the result to a patient. Securely? Well, yes. The appointment will contain PHI, so I will utilize the secure email function of our email system. They wanted some data that the EHR could not place into the order, so I had to look that data up from the database and place it into the email.
So much for the outbound "order." Now, for the returned results.
A Radiology Result is just a special type of Clinical Document.
We have an existing document interface which we use to receive clinical documents from this trading partner as ORU^R01 messages. They will place these radiology documents into that stream and I will have to select those messages, process them a little bit differently and send them to the EHR. I will need to look up our patient identifier and put it into the message in place of their patient identifier. I will also look up the NPI for each of the incoming providers and place that into the message. The sending system gives us their internal identifier for each provider, and the EHR would like to see the NPI instead.
We are still developing this interface. The outbound orders seem to be working fine. I have built the results processing route and am waiting to get a test result to see if I have built that correctly.
We want to send Radiology Orders from our EHR system to our trading partner and want the Radiology Results document to be returned electronically and placed into the patient's chart in the EHR.
Simple. Right.
Except, the scheduling system at our trading partner will not receive the order. I suggested that we send them an order message (ORM), a scheduled appointment (SIU), and a registration message for a future encounter (ADT). They told us that they could not process any of those HL7 messages into their scheduling system. So, we settled on this kluge. I will convert the order message into an email that I will send securely to the scheduling department. They will then manually key the appointment into their system. Hopefully, they will remember to key our Order Number so that I can match the result to a patient. Securely? Well, yes. The appointment will contain PHI, so I will utilize the secure email function of our email system. They wanted some data that the EHR could not place into the order, so I had to look that data up from the database and place it into the email.
So much for the outbound "order." Now, for the returned results.
A Radiology Result is just a special type of Clinical Document.
We have an existing document interface which we use to receive clinical documents from this trading partner as ORU^R01 messages. They will place these radiology documents into that stream and I will have to select those messages, process them a little bit differently and send them to the EHR. I will need to look up our patient identifier and put it into the message in place of their patient identifier. I will also look up the NPI for each of the incoming providers and place that into the message. The sending system gives us their internal identifier for each provider, and the EHR would like to see the NPI instead.
We are still developing this interface. The outbound orders seem to be working fine. I have built the results processing route and am waiting to get a test result to see if I have built that correctly.
Thursday, October 14, 2010
Patient List Interface
Here is a cute, little interface project that I knocked out in a couple of days.
One of our business partners is sending us what they call "patient list" data. This is information on patient groupings. For example, a patient could be on the "Gastroenterology Consults" list. This is information that does not come across in the organizations ADT stream, and the likelihood of getting it added to that was pretty low. Instead, they send us a patient list file which would contain a record for each patient and the patient list that they are on. They generate this as a Comma Separated Value (CSV) file and would send that to us as a flat file. I built a route and a mapping in the engine to take the flat file, generate an HL7 A08 (patient udate) message for each patient and place the Patient List information into the PV2-23 field (ClinicOrganizationName). The route then places each ADT message into the ADT stream for the appropriate system.
The A08 updates the basic patient demographic information by only adding the patient list information to the PV2-23 field ClinicOrganizationName. They can then select all patients that are currently in the Neurology list, for example. The receiving system gets the Patient List information with no changes required.
We already had a mechanism in place to exchange flat files, so they added this file to the stream. On the receiving end I have a script that looks at each file, identifies which one it is and routes it for processing. I added the new file to the script and built a new route to process the patient list file.
I then had to build a data structure for the CSV, which was pretty straightforward. I then built a special ADT structure that contained multiple A08 messages, and then a Map (that is the Rhapsody term, in Cloverleaf, this would be a Translate) to map the data from the CSV file to the ADT Message. After this, I added a DeBatch filter to the route to split each of the A08s into a separate message.
I had not built this sort of interface before, so I learned a little bit doing it. The trickiest part was getting the file structure definitions set up correctly. The actual mapping took about an hour to build and test.
One of our business partners is sending us what they call "patient list" data. This is information on patient groupings. For example, a patient could be on the "Gastroenterology Consults" list. This is information that does not come across in the organizations ADT stream, and the likelihood of getting it added to that was pretty low. Instead, they send us a patient list file which would contain a record for each patient and the patient list that they are on. They generate this as a Comma Separated Value (CSV) file and would send that to us as a flat file. I built a route and a mapping in the engine to take the flat file, generate an HL7 A08 (patient udate) message for each patient and place the Patient List information into the PV2-23 field (ClinicOrganizationName). The route then places each ADT message into the ADT stream for the appropriate system.
The A08 updates the basic patient demographic information by only adding the patient list information to the PV2-23 field ClinicOrganizationName. They can then select all patients that are currently in the Neurology list, for example. The receiving system gets the Patient List information with no changes required.
We already had a mechanism in place to exchange flat files, so they added this file to the stream. On the receiving end I have a script that looks at each file, identifies which one it is and routes it for processing. I added the new file to the script and built a new route to process the patient list file.
I then had to build a data structure for the CSV, which was pretty straightforward. I then built a special ADT structure that contained multiple A08 messages, and then a Map (that is the Rhapsody term, in Cloverleaf, this would be a Translate) to map the data from the CSV file to the ADT Message. After this, I added a DeBatch filter to the route to split each of the A08s into a separate message.
I had not built this sort of interface before, so I learned a little bit doing it. The trickiest part was getting the file structure definitions set up correctly. The actual mapping took about an hour to build and test.
Friday, June 11, 2010
Restarting Interfaces
We recently changed five existing interfaces to "pass through" the Rhapsody interface engine that I am working with. These interfaces are made via a vpn tunnel between the two organizations.
That first day, one of the interfaces stopped working several times. I stopped and started the communication point on my end, and the connection was re-established and messages began to flow, again.
The next morning, one of the interfaces had not seen messages cross for seven hours. I again stopped and started the communication point, and messages began to flow.
I was told that "they do that all the time."
The next morning, three of the five new interfaces had stopped overnight. I restarted them, they connected and messages began to flow.
I have seen this sort of behavior with interfaces that cross through VPNs. When the interface is inactive, the vpn shuts down, but the receiving end still thinks that it has a connection. The sending end will try to re-establish a connection, but since the receiving side still thinks that it has a connection, the new connection is refused.
Being the cautious person that I am, I changed one of the three communications points to restart every hour. The interface would stop, reconnect, and messages would begin to flow, again. I wanted to see one of them work before I changed anything else.
Once I saw that this worked, I made similar changes to the other two interfaces that had exhibited similar issues. Two of the five original interfaces had not shown any issues. One was an ADT feed that constantly had traffic. The other received a "batch" of messages every morning. It would reconnect, deliver the messages, and then disconnect.
So far, the hourly re-start seems to be working. For years, these interfaces had failed. A trouble ticket would be opened, and an operator would manually stop and start the interface to get things working, again. Based on previous experience, I was able to diagnose the problem and implement a simple fix. This will save our business partner opening trouble tickets and our operators from manually restarting these interfaces.
One small step...
That first day, one of the interfaces stopped working several times. I stopped and started the communication point on my end, and the connection was re-established and messages began to flow, again.
The next morning, one of the interfaces had not seen messages cross for seven hours. I again stopped and started the communication point, and messages began to flow.
I was told that "they do that all the time."
The next morning, three of the five new interfaces had stopped overnight. I restarted them, they connected and messages began to flow.
I have seen this sort of behavior with interfaces that cross through VPNs. When the interface is inactive, the vpn shuts down, but the receiving end still thinks that it has a connection. The sending end will try to re-establish a connection, but since the receiving side still thinks that it has a connection, the new connection is refused.
Being the cautious person that I am, I changed one of the three communications points to restart every hour. The interface would stop, reconnect, and messages would begin to flow, again. I wanted to see one of them work before I changed anything else.
Once I saw that this worked, I made similar changes to the other two interfaces that had exhibited similar issues. Two of the five original interfaces had not shown any issues. One was an ADT feed that constantly had traffic. The other received a "batch" of messages every morning. It would reconnect, deliver the messages, and then disconnect.
So far, the hourly re-start seems to be working. For years, these interfaces had failed. A trouble ticket would be opened, and an operator would manually stop and start the interface to get things working, again. Based on previous experience, I was able to diagnose the problem and implement a simple fix. This will save our business partner opening trouble tickets and our operators from manually restarting these interfaces.
One small step...
Subscribe to:
Posts (Atom)