This is Info file appman.info, produced by Makeinfo-1.64 from the input file appman.texi. This text describes the concepts, operation, and maintenance of the ProtoGen/HL7 interface to HP's clinical information system CareVue as well as the ASTM to HL7 converter for the acid base laboratory Radiometer ABL 500 and 600 series. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. Copyright (C) 1996 Gunther Schadow  File: appman.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) ProtoGen Interfacing Software ***************************** This text describes the concepts, operation, and maintenance of the ProtoGen/HL7 interface to HP's clinical information system CareVue/9000 as well as the ASTM to HL7 converter for the acid base laboratory Radiometer ABL 300, 500 and 600 series. The reader is supposed to know how to operate and configure the ABL and CareVue systems, to have basic knowledge about HL7 and ASTM medical communication protocol as well as the UNIX suite of operating systems and C/C++ programming. This text does not describe the ProtoGen system in general but only those parts of it that is relevant for running and configuring the Radiometer and CareVue interface application programs. * Menu: * Overview:: Overview * Radiometer:: Radiometer Interface * CareVue Interface:: CareVue Interface * Databases:: Common Files and Databases  File: appman.info, Node: Overview, Next: Radiometer, Prev: Top, Up: Top Overview ******** The ProtoGen interface application programs perform two basic tasks: 1. convert output of the Radiometer instruments to HL7 2. convert a "standard"(1) HL7 to CareVue's dialect of HL7 and forward the message to the CareVue HL7 interface Communication from Radiometer instruments and to CareVue uses serial lines. The operation of serial lines has been separated from the message handling and conversion. On the ABL side, the `radioshell' program configures the serial device and accepts messages which it pipes them to the `abl500' program for ABL 500 and 600 series or to the `abl300' program for the ABL 300. The `abl500' program reads the ASTM message that was sent by the ABL 500 via the `radioshell' from the standard input and transforms it to a HL7 ORU message using the LOINC code and ISO+ units. The HL7 message is written as a message file to a spool directory. At fixed time intervals, triggered by cron(8), there is a shell script `hl7tocv' that forwards all message files in the spool directory to the `cvgateway' that is running as a demon in the background. The `cvgateway' listens at a TCP port (named "carevuehl7" in `/etc/services') and converts the "standard" HL7 message to CareVue's HL7 dialect (cvHL7). The cvHL7 message is then forwarded to an other TCP port ("carevuefsi") where the `llpdrv' program acts as a relay for the ANSI X3.28 serial line to CareVue's FSISERVER. The `cvgateway' program uses the LabEventInfo database in order to hand lab results to the CareVue system formatted properly according to the configuration of the CareVue system. Therefore the CareVue system's LabEventMap table should always be configured using the LabEventInfo database. The `radioshell', `hl7tocv', and `cvgateway' programs write their input messages as files into a journal directory, used for monitoring the proper work of system. The databases for LOINC and ISO+ unit codes, as well as for the LabEventInfo databases are created and maintained with their respective "manager" programs (`loincmgr', `unitmgr', and `LabEventInfoMgr') using their human readable tabular form stored in the `.tab' files. * Menu: * Files:: Files and Directories * Addressing:: Application and Facility * ILLP:: The Internal Protocol ---------- Footnotes ---------- (1) The word "standard" is set in quotes because it shouldn't be necessary to distinguish a standard standard from a non-standard standard. However, HL7 is not rigid enough in order to prevent this paradox.  File: appman.info, Node: Files, Next: Addressing, Prev: Overview, Up: Overview Files and Directories ===================== The application software built on top of the ProtoGen HL7 and ASTM interface libraries as well as the libraries themselves use a common set of files and directories for development and runtime. The exact paths are configurable at compile time and may vary between installations. Supposedly they are single rooted in `/usr/hl7' or `/usr/local/hl7'. Within this directory there are the following subdirectories: `bin' the executable programs `etc' various files needed during runtime as well as data files that allow reconfiguration of parts of the system, like codes databases in the tabular form. `include' the include header files. Subdirectories are `hl7', `astm', `hl7/CareVue', and `hl7/ukbf'. These files are used exclusively for development. `lib' the object code libraries `libpg.a', `libhl7.a', `libastm.a', `libhl7cv.a', and `libukbf.a'. Like the `include' directory these files are used only for development. `lib/codes' the codes databases in the database form used at runtime of the system. The database files are built from the tabular form using a "manager" program, thus the files here need never be touched. `var/log' log and journal file area `var/spool' area for outgoing message files Most programs use the syslog service of the operating system in order to log runtime error, warning and informational messages. Note that some runtime logfiles are written into /tmp and /var/tmp directory, which is of course to be reorganized in future versions.  File: appman.info, Node: Addressing, Next: ILLP, Prev: Files, Up: Overview Application and Facility ======================== Since HL7 messages are not bound to one specific transport protocol, it doesn't define a specific addressing scheme. Instead HL7 defines two fields per address the one called the APPLICATION and the other the FACILITY. Where not otherwise stated, we use these fields as follows: FACILITY A department like a care-unit. APPLICATION The name of an application program or type. Particularly we presume the notion that one facility has one or more applications. The example facility used here is `060_IOP' and applications are `ABL', `CVGATEWAY', `ADT', `CLI', and `TEST'. Other HL7 interfaces might interpret these data items differently, however, the interpretation used here corresponds at least to the interpretation used by the CareVue system. Each message has a sending application/facility and a receiving application/facility. The fields are optional, even though addresses are essential to message routing. Since the routing problem is not yet generally addressed, neither here nor in HL7, and since ProtoGen applications use direct addressing (IP addresses, files or devices), the application/facility names do not have uniform functions.  File: appman.info, Node: ILLP, Prev: Addressing, Up: Overview The Internal Protocol ===================== All ProtoGen applications prefer to use TCP/IP networking communications driven by a very simple lower layer protocol, called the "Internal LLP" (ILLP). The ILLP just provides some session layer support on top of the fine TCP transport protocol. The ILLP resembles the new T/TCP protocol (1) in many respects. Assumptions ----------- The internal LLP assumes that a transaction is the exchange of one pair of messages. The `request message' is passed from the client to the server, which sends a `response message' back to the client. It is meant to meet the following needs: 1. be as simple as possible 2. signal the end of a message as an `end of file' 3. allow a site to cancel and restart the message that it is currently about to send The internal LLP is supposed to use UNIX domain stream type sockets as it's channel and probably will not run on any other channel. This is because the protocol depends on specific properties of the channel that only the UNIX domain stream type socket has: Reliable sequenced unduplicated transport of data bytes governed by a stream semantic along with the immediate notification of the existence of out-of-band data. The latter property is not guaranteed by Internet domain TCP type sockets. It is because of this, that the internal LLP is never an option for transactions between different machines. Unfortunately out-of-band (OOB) messages are not supported on 4.3BSD (Net2), 4.4BSD (lite), and HPUX-9 UNIX domain sockets, nor am I aware of any Unix system that does implement OOB data for Unix domain sockets and I suspect that there is no such implementation at all. However OOB data is supported in Internet domain sockets, with the limitation that transmission may be delayed. Normal Operation ---------------- CLIENT SERVER A. CONNECTION SETUP 1. connect to server accept connections yields newly opened, bidirectional, stream type socket 2. write read from-address as a character string delimited by ASCII STX B. REQUEST MESSAGE 3. write read message data 4. shutdown write part of read returns 0 delivered as socket `end of file' condition to higher layers C. RESPONSE MESSAGE 5. read write message data 6. read returns 0 delivered as shutdown write part of `end of file' condition to socket higher layers D. CONNECTION SHUTDOWN 7. socket became unusable since it is mutually widowed on both ends close socket close socket Exceptions ---------- Restart Message ............... The site which is about to send a message may restart the transmission of the same message by sending the single ASCII character STX out of band. The other site is notified of the exception by a SIGURG signal. Upon reception of SIGURG the receiving site discards all data up to the mark, which indicates when the exception occurred. The receiver restarts reception of the message immediately after that mark. Cancel Transaction .................. The site which is about to send a message may cancel the whole transaction by sending the single ASCII character CAN out of band. The other site is notified of the exception by a SIGURG signal. Any site may abort the transaction without further notification when it is not currently about to send a message. The notification is only necessary in order to allow the receiving process to distinguish between normal end of message block and abort. ---------- Footnotes ---------- (1) `R. Braden, T/TCP - TCP Extensions for Transactions, RFC 1644'  File: appman.info, Node: Radiometer, Next: CareVue Interface, Prev: Overview, Up: Top Radiometer Interface ******************** * Menu: * radioshell:: The `radioshell' program * abl500:: An ASTM to HL7 Gateway for the ABL 500 * abl300:: Converting Printer Output to HL7 * PatByBed:: Resolving a Patient ID * OperByNum:: Resolving an Operator ID  File: appman.info, Node: radioshell, Next: abl500, Prev: Radiometer, Up: Radiometer Accepting Messages From a Serial Line ===================================== Synopsis ........ radioshell 3|5|6 COMMAND TTY Description ........... This program does nothing else than to read one peace of output from the computer interface of the Radiometer ABL 300, 500, or 600 series of acid base laboratories into a buffer. Since the ABL 300 has no soft flow control capabilities but is connected through a two wires fiber optical line there is no handshake. The HL7 interfaces can not process the incoming data at the required rate which results in lost characters. The ABL 500 and 600 series, though capable of doing soft flow control, require the `radioshell' as well since the ASTM to HL7 translation might be too slow, especially when multiple subsequent ASTM messages arrive at a fast rate. The `radioshell' is a small program that can read from the serial line very quickly. It buffers the data and invokes the HL7 interface in the background, piping to it the data read into the buffer. The main process of `radioshell' immediately resumes listening to the serial line. Moreover, `radioshell' takes over serial line related configuration headache. The `radioshell' program makes use of the simple "message" formats of the ABL: ABL 300 Each line is exactly 21 bytes long: 20 data bytes and 2 end of line chars (CR LF) which are mapped to a single LF by the tty device (igncr flag set). When such a data block is not ended by LF, we know that something went wrong before and made us get out of sync. Thus we issue a warning and discard the message that is currently being sent. A message ends when the last two lines read have been blank. A message is expected to never exceed 50 lines, thus the buffer is 50 * 21 bytes + 1 = 1051 in length including a terminating NUL byte. ABL 500 and 600 The message format uses ASCII control characters as delimiters: STX BLK ..... ETX. While STX and ETX are standard ASCII control characters, the BLK resembles the "link block number" of the ANSI X3.28 protocol: It is the current message number taken modulo 8 and converted to an ASCII digit in the range of '0' to '7'. The buffer size is fixed to 8192 bytes for the ASTM message. Options ....... Arguments to this program are: the selection flag for the type of ABL. This selects the message format to be used. A subsequent arbitrary number of arguments set the command to be invoked for each message read. If this is specified to `-', a default command is used (`/usr/hl7/bin/abl300' or `/usr/hl7/bin/abl500') The *last* argument is the path to the device node of the serial line (tty). If the tty argument is `-', the standard input is used instead. The TTY parameter are hard coded into the `radioshell' program as follows: ABL 300 300 bps, 7 bits, even parity, local mode, no flow control, ignore CR (igncr) ABL 500 and 600 series 9600 bps, 8 bits, no parity, local mode, soft flow control (ixon/ixoff) Examples ........ Typically, the `radioshell' is used as a `getty(8)' program specified in `/etc/ttys' or `/etc/inittab'. `/etc/ttys': ttyd0 "radioshell 625 -" unknown on ttyd1 "radioshell 300 -" unknown on Files ..... `/usr/hl7/var/log/ABL/060_IOP/ABL####' The `radioshell' program writes a copy of each message as a file to a directory whose name is composed of the APPLICATION and FACILITY names. The filename is composed of the string `ABL' and the process id (PID) of the `radioshell' child process attached to it. Bugs .... The APPLICATION name (`ABL') and the FACILITY name (`060_IOP') are chosen at compile time. This is certainly wrong because the `radioshell' might well be used for different facilities. The process id is certainly a bad choice for numbering files, because process ids will repeat and thus do not reflect the order in time of the messages. Diagnostics ........... Messages are logged with syslog(3) and are most probably be found in the system directory `/var/log/messages'. See Also ........ `ttys(5)', `termios(4)', `getty(8)', `ascii(7)', `syslog(3)', *Note abl300::, *Note abl500::.  File: appman.info, Node: abl500, Next: abl300, Prev: radioshell, Up: Radiometer An ASTM to HL7 Gateway for the ABL 500 ====================================== Synopsis ........ abl500 [-d] Description ........... The `abl500' program converts an ASTM message received from a Radiometer ABL 500 or 600 series acid base laboratory via the standard input to an HL7 ORU message written as a message file to a spool directory. The following mapping is used for the ASTM message: ASTM RESULT MESSAGE | HL7 OBSERV RESULT/UNSOLICITED ================================|================================== | H.............................+.......MSH {.............................+.......{ P...........................+.........[ . | PID . | [ { NTE } ] . | [ PV1 ] .......................+.........] {...........................+.........{ . | [ ORC ] . O.........................+...........OBR . | [ { NTE } ] . {.........................+...........[ . . | { . .R........................+...............OBX . . | [ { NTE } ] . . | } . }.........................+...........] }...........................+.........} }.............................+.......} L | [ DSC ] Where the data items are mapped as follows: ASTM MESSAGE | HL7 ORU MESSAGE DATA ITEM TYP N | DATA ITEM TYP N ============================================================================ H.SENDER(5) ZA 0--1 > MSH.SENDING APPLICATION ST 1 > MSH.SENDING FACILITY ST 1 ZA.BRAND | ZA.ID | | H.DATE/TIME OF MESSAGE(14) TS 0--1 ? MSH.DATE/TIME OF MESSAGE TS 1 | P.SEQUENCE NUMBER(1) SI 0--1 = MSH.SET ID - PATIENT ID SI 1 P.LAB ASSIGNED PATIENT ID(3) ID 0--1 = PID.ALTERNATE PATIENT ID P.PATIENT NAME(5) PN 0--1 | PID.PATIENT NAME patinfo()... P.SEX(8) 0001 ID 0--1 | PID.SEX P.PATIENT AGE(14) CQ 0--1 | -- P.PATIENT HEIGHT(16) CQ 0--1 | -- P.PATIENT WEIGHT(17) CQ 0--1 | -- P.LOCATION(26) ID 0--1 | PV1.ASSIGNED PATIENT LOCATION | O.SEQUENCE NUMBER(1) SI 0--1 = OBR.SET ID OBSERVATION REQUEST O.INSTRUMENT SPECIMEN ID(3) ZI 0--1 = OBR.FILLER ORDER NUMBER CM ZI.TYPE 1005! ID | CM.COM2 ZI.NUMBER SI | CM.COM1 | O.SPECIMEN COLLECTION DATE/TIME TS 0--1 = OBR.OBSERVATION DATE/TIME O.SPECIMEN DESCRIPTOR(15) ZS 0--1 > OBR.SPECIMEN SOURCE ZS.TYPE 1001! ID | ZS.SOURCE 1002! ID | | R.SEQUENCE NUMBER(1) SI 0--1 = OBX.SET ID - OBSERVATIONAL SIMPLE R.UNIVERSAL TEST ID(2) ZT 0--1 | OBX.OBSERVATION IDENTIFIER toloinc() ZT.PARAMETER NAME 1003! ID | ZT.PARAMETER TYPE 1004! ID | | R.MEASUREMENT VALUE(3) ST 0--1 > OBX.OBSERVATION VALUE ...(tounit()) R.UNITS(4) 0003! ID 0--1 > OBX.UNITS tounit() R.ABNORMAL FLAG(6) 0078 ID 0--1 = OBX.ABNORMAL FLAGS R.RESULT STATUS(8) 0085 ID 0--1 = OBX.OBSERV RESULT STATUS R.OPERATOR ID(10) ID 0--1 > OBX.RESPONSIBLE OBSERVER operinfo() R.DATE/TIME TEST STARTED(11) TS 0--1 = OBX.DATE/TIME OF THE OBSERVATION R.INSTRUMENT ID(13) 1006! ID 0--1 = OBX.PRODUCER'S ID | L.SEQUENCE NUMBER(1) SI 0--1 | -- L.TERMINATION CODE(2) 1007! ID 0--1 | -- (check) The ABL 500 and 600 allows the operator to enter a patient id consisting of digits and colons as well as an operator id consisting of a string of digits. It is assumed, that the patient identifier is the room and bed number where the patient is currently located. This is a reasonably unique number that is not too long in order to prevent errors from being introduced. In order to resolve this identifiers the shell scripts `/usr/hl7/etc/PatByBed' and `/usr/hl7/etc/OperByNum' are called in a reading pipe. These scripts can be configured to make a database access in order to resolve the numbers to real patient or operator data. See *Note PatByBed:: and *Note OperByNum:: for how to configure these scripts. The observation identifiers are coded using the LOINC code (see *Note LOINC::) which had to be substantially extended in order to map ABL results. However, still some results from the ABL 625 are not resolved due to missing entries in the LOINC database table. Resolved observation identifiers are: General `T' `BODY TEMPERATURE, TEMP' `B' `BAROMETRIC PRESSURE, PRES' Blood Gases `pCO2' `CARBON DIOXIDE, PPRES' `pCO2(T)' `CARBON DIOXIDE^^ADJUSTED TO BODY TEMPERATURE, PPRES' `tCO2(B)' `CARBON DIOXIDE.TOTAL, SCNC' `tCO2(P)' `CARBON DIOXIDE.TOTAL, PLAS' `pO2' `OXYGEN, PPRES' `pO2(T)' `OXYGEN^^ADJUSTED TO BODY TEMPERATURE, PPRES' `p50(act)' `OXYGEN^^SATURATION ADJUSTED TO 0.5, PPRES' `p50(act),T' `OXYGEN^^SATURATION ADJUSTED TO 0.5 AND BODY TEMPERATURE, PPRES' `p50(st)' `OXYGEN^^SATURATION ADJUSTED TO 0.5 STANDARD, PPRES' `sO2' `OXYGEN SATURATION, SFR' `tO2' `OXYGEN.TOTAL, SCNC' Acid Base Status `pH' `PH, SCNC' `pH(st)' `PH^^STANDARD, SCNC' `pH(T)' `PH^^ADJUSTED TO PATIENT TEMPERATURE, SCNC' `HCO3-' `BICARBONATE, SCNC' `SBC' `BICARBONATE^^STANDARD, SCNC' `ABE' `BASE EXCESS, SCNC' `SBE' `BASE EXCESS^^STANDARD, SCNC' Electrolytes `Na+' `SODIUM, SCNC' `K+' `POTASSIUM, SCNC' `Ca++' `CALCIUM.FREE, SCNC' `Ca(7.4)' `CALCIUM.FREE^^PH ADJUSTED TO 7.4, SCNC' `Cl-' `CHLORIDE, SCNC' `Anion gap (K+)' `ANION GAP^^INCLUDING POTASSIUM, SCNC' `Anion gap' `ANION GAP, SCNC' Metabolism `Glu' `GLUCOSE, ACNC' `Lact' `LACTATE, SCNC' Hematology `Hct' `HEMATOCRIT, NFR' `tHb' `HEMOGLOBIN, MCNC' `O2CAP' `OXYGEN BINDING CAPACITY, SCNC' `O2Hb' `OXYHEMOGLOBIN.TOTAL, NFR' `RHb' `DEOXYHEMOGLOBIN, SFR' `MetHb' `METHEMOGLOBIN, MFR' `COHb' `CARBON MONOXIDE.HEMOGLOBIN, NFR' `HbF' `HEMOGLOBIN F, SFR' `SHb' `SULFHEMOGLOBIN, SFR' Miscellanea `CO2' `CARBON DIOXIDE, NFR' `FIO2' `OXYGEN INHALED, NFR' `O2' `OXYGEN, NFR' Unresolved observation identifiers are: `pO2(A)', `pO2(A),T', `AaDpO2', `AaDpO2,T', `a/ApO2', `a/ApO2,T', `RI', `RI,T', `DO2', `VO2', `RQ', `Qt', `Qx', `cx', `px', `Shunt', `Shunt,T', `pO2(uv)', and `CQ'. The LOINC code for specimen is used instead of the HL7 code in order to be consistent with LOINC which is being developed in close relationship to HL7. The HL7 table 70 is anyway hopelessly incomplete. Thus, instead of `ABLD' we keep saying `BLDA' for arterial blood. However, even the LOINC code is not detailed enough in order to distinguish venous blood `BLDV' from mixed venous blood. The latter is therefore encoded by `BLDVM'. If a test was erroneous, the ABL 500 uses a question mark `?' before the numeric observation value. Currently such observations are simply discarded. Likewise, `<' and `>' characters that designate results beyond absolute limits cause the observation to be discarded. In subsequent versions, however, these will cause abnormal flags to be set and an NTE segment to be added, giving a textual note on the error. Options ....... `-d' Set log level to log everything down to debug level. Examples ........ For proper operation, `abl500' should be called from the `radiometer' program. radiometer 625 /usr/hl7/bin/abl500 - /dev/ttyd0 But single abl messages can be converted to HL7 directly: abl500 < /usr/hl7/var/log/ABL/060_IOP/ABL0123 Environment ........... `PG_CODELIB' The location of the external code databases for LOINC, LabEventInfo and units. This is rarely used, since everyone uses the names compiled into the programs. Files ..... `/usr/hl7/var/spool/ABL/060_IOP/msg#########.dat' The `abl500' program the HL7 ORU message as a message file to a spool directory whose name is composed of the APPLICATION and FACILITY names. The filename is composed of the string `msg' and the time in seconds since the UNIX epoch with the process id (PID) of the abl500 process attached to it and the suffix `.dat'. `/usr/hl7/var/spool/ABL/060_IOP/msg#########.lck' While the message file is written out, the corresponding lock file appears in the spool directory, indicating that the message file might be incomplete. `/tmp/abl500.log' The run log file, if syslog(3) is not used instead. Bugs .... The colon in the patient id is transformed into a `-' character while the id itself is always interpreted as `ROOM:BED'. This is definitely too narrow, since one might want to use different numbers. We should not interpret anything here and directly forward the number to PatByBed. Uncoded observation identifiers: `pO2(A)', `pO2(A),T', `AaDpO2', `AaDpO2,T', `a/ApO2', `a/ApO2,T', `RI', `RI,T', `DO2', `VO2', `RQ', `Qt', `Qx', `cx', `px', `Shunt', `Shunt,T', `pO2(uv)', and `CQ'. The APPLICATION name (`ABL') and the FACILITY name (`060_IOP') are chosen at compile time. This is certainly wrong because the abl500 program might well be used for different facilities. See Also ........ `syslog(3)', `time(3)', *Note PatByBed::, *Note OperByNum::, *Note radioshell::. *Note abl300::,  File: appman.info, Node: abl300, Next: PatByBed, Prev: abl500, Up: Radiometer Converting Printer Output to HL7 ================================ Synopsis ........ abl300 [-d] DEVICE SERVICE HOST Description ........... The `abl300' program reads a printer output from the ABL 300 device attached to DEVICE and translates it to HL7. It is built using lex(1) and yacc(1). English and German scanner code for lex(1) is available and chosen at compile time. Messages are forwarded directly to a TCP/IP address at host HOST and port SERVICE using the ILLP protocol. Options ....... `-d' Set log level to log everything down to debug level. If DEVICE is set to `-' the standard input is used instead. Examples ........ For proper operation, `abl300' must be called from the `radiometer' program. radiometer 300 /usr/hl7/bin/abl300 - carevuehl7 localhost /dev/ttyd0 But single abl messages can be converted to HL7 directly: abl300 - carevuehl7 localhost < /usr/hl7/var/log/ABL/060_IOP/ABL0123 Environment ........... `PG_CODELIB' The location of the external code databases for LOINC, LabEventInfo and units. This is rarely used, since everyone uses the names compiled into the programs. Files ..... `/usr/hl7/var/log/ABL/060_IOP/REQ####' The abl300 program writes a copy of each HL7 message as a file to a directory whose name is composed of the APPLICATION and FACILITY names. The filename is composed of the string `REQ' and the process id (PID) of the abl300 process attached to it. `/usr/hl7/var/log/ABL/060_IOP/ACK####' Likewise the acknowledgment HL7 message is written into the same directory with the same PID number attached to the prefix `ACK'. `/tmp/abl300.log' The run log file, if syslog(3) is not used instead. Bugs .... The `abl300' program is not supported thoroughly any more and this documentation is incomplete. Bugs may be introduced as the ProtoGen system evolves without this program to be further tested. If the transport of the HL7 message to the destination address fails, the message is lost. No retry is made. Should use a message file written to a spool directory instead. The APPLICATION name (`ABL') and the FACILITY name (`060_IOP') are chosen at compile time. This is certainly wrong because the abl300 program might well be used for different facilities. The process id is certainly a bad choice for numbering files, because process ids will repeat and thus do not reflect the order in time of the messages. Diagnostics ........... The `ACK####' message file will contain error messages from the destination of the ORU HL7 messages. See Also ........ `syslog(3)', *Note radioshell::, *Note PatByBed::, *Note OperByNum::, *Note abl500::.  File: appman.info, Node: PatByBed, Next: OperByNum, Prev: abl300, Up: Radiometer Resolving a Patient ID ====================== Synopsis ........ /usr/hl7/etc/PatByBed ID Description ........... The `PatByBed' script is used to resolve a patient identifier as entered by the operator into the radiometer device into real patient data, including medical record number, name and date of birth. The script performs arbitrary commands and returns one line of output to the standard output device, which specifies the following data items: 1. visit number 2. internal patient id 3. last name 4. first name 5. date of birth 6. sex Optional double quotes `"' may be used in order to mark strings with inherent spaces or tabs. The data items should be delimited by single ASCII HT (tab, 0x0A) characters. The keyword NULL, all-uppercase without quotes, stands for the database NULL value. The date of birth is formatted as `DDXMMX[CC]YY' where X is any non numeric character Examples ........ The `PatByBed' script is called as a reading pipe from the `abl300' and `abl500' programs: /usr/hl7/etc/PatByBed 601-1 For the ABL to CareVue interface chain, a remote shell is used in order to directly log into the CareVue host, where an `idb' job is called to fetch the patient data: #!/bin/sh rsh -K -l $CVUSER $CVHOST " . /usr/M1215A/carevue/etc/carevue_env ; . /usr/M1215A/carevue/etc/go_charting ; idb -s -q 2>/dev/null <<__END__ set ColumnMode; set WaitMode; select objectId into BEDOID from BedConfig where name=\"$1\"; select prid into PATID from PtVisit where inBed=(BedConfig,\\\$BEDOID); set Patient \\\$PATID; select acctNum, medRecNum, name, Vorname, DOB, sex from CfgPatients; __END__ " A sample output might be: "12345" "08/15-7411" "Doe" NULL "19/02/1969" "M" Environment ........... `CVUSER' `CVHOST' used in the above example script for the user and host to log into a CareVue host. Note that this is not fixed. The actual policy used to dynamically configuring the user and host is described in *Note carevuehost:: See Also ........ `sh(1)', `rsh(1)', `idb(1)', *Note abl300::, *Note abl500::.  File: appman.info, Node: OperByNum, Prev: PatByBed, Up: Radiometer Resolving an Operator ID ======================== Synopsis ........ /usr/hl7/etc/OperByNum ID Description ........... The `OperByNum' script is used to resolve an operator identifier as entered by the operator into the radiometer device into real operator data, including the name. The script performs arbitrary commands and returns one line of output to the standard output device, which specifies the following data items: 1. last name 2. first name Optional double quotes `"' may be used in order to mark strings with inherent spaces or tabs. The data items should be delimited by single ASCII HT (tab, 0x0A) characters. The keyword NULL, all-uppercase without quotes, stands for the database NULL value. Examples ........ The `OperByNum' script is called as a reading pipe from the `abl300' and `abl500' programs: /usr/hl7/etc/OperByNum 1919 For the ABL to CareVue interface chain, a remote shell is used in order to directly log into the CareVue host, where an `idb' job is called to fetch the patient data: #!/bin/sh rsh -K -l $CVUSER $CVHOST " . /usr/M1215A/carevue/etc/carevue_env ; . /usr/M1215A/carevue/etc/go_charting ; idb -s -q 2>/dev/null <<__END__ set ColumnMode; select nameLast, nameFirst from User where employeeNo=\"$1\"; __END__ " A sample output might be `"Schadow" NULL' Environment ........... `CVUSER' `CVHOST' used in the above example script for the user and host to log into a CareVue host. Note that this is not fixed. The actual policy used to dynamically configuring the user and host is described in *Note carevuehost:: See Also ........ `sh(1)', `rsh(1)', `idb(1)', *Note abl300::, *Note abl500::.  File: appman.info, Node: CareVue Interface, Next: Databases, Prev: Radiometer, Up: Top CareVue Interface ***************** The HP CareVue/9000 system has a "foreign systems interface" (FSI) that supports a limited HL7 dialect. The task of the gateway is to map "standard" HL7 messages to CareVue's dialect of HL7 (cvHL7). The particular transformations performed are dependent on both, cvHL7 and the actual configuration of the CareVue system. Since the latter may vary from one installation to the other it is likely that the gateway program will not work "out of the box" but needs some adjustments. A lot is configurable at runtime by databases and the like, but some properties must be adjusted in the source code. This affects mainly the configuration of the user configurable patient demographics (ZDM) segment of cvHL7. However, since the configuration of the ZDM segment tends to be stabile over years, this limitation it is not too much of a problem. The major differences between cvHL7 and "standard" HL7 are: the ZDM segment This is a segment that is placed at the end of ADT messages. It is required and very important, because CareVue does not use the HL7 standard data items for updating its patients demographic data. It rather maps the strings found in the ZDM segment to its preconfigured and user configurable patient data, like name, medical record number, etc. message structure is defined slightly different. For instance, the ORU message may not have a PV1 segment. patient reference patients are referenced by the CareVue's `medRecNum'. This number is expected in the `PID.PatIdIntId' field of any HL7 message. However, the CareVue system might be configured such that visit numbers (`PV1.VisitNum') are used as patient ids instead, thus the gateway must exchange both numbers. The cvHL7 interface of CareVue currently consists of three applications. The following table lists the application names along with the messages they can receive: ADT the ADT application receives ADT messages: A01, A02, A03, A08, A11, A12, A13, and A17 CLI the clinical laboratory application receives ORU messages RX the pharmacy orders application receives (!) pharmacy orders - this is not implemented in this gateway and no documentation from HP is available for it whatsoever. Note that the CareVue interface does only receive messages and sends an acknowledgment, with the exception of network management (NMD) messages, which it is capable to originate. However, this facility of (doubtful use) *must* be turned off for use with this gateway. NMD messages can be sent to each of the applications and are acknowledged by them. The way that CareVue acknowledges request messages is quite disturbing. For instance, a positive acknowledgment (AA) for an admission (A01) does not guarantee the patient to be really admitted in the CareVue census. If the selected bed was already occupied no error is reported on HL7 level. On the other hand, one might receive an application error (AE) if an ORU message reports the same results twice for one date/time. The gateway must therefore test preconditions to messages in order to guarantee them to be reasonably effective where possible, and must reject those that can not be successful even though CareVue might acknowledge them positively. * Menu: * ADT:: The ADT Application * CLI:: The Result Report Application * cvgateway:: The HL7 to CareVue Gateway Program * idb_direct:: Direct Access to CareVue's Database * LabEventInfo:: Configuring Results Mapping * hl7tocv:: The `hl7tocv' Program * llpdrv:: The LLP Driver Program  File: appman.info, Node: ADT, Next: CLI, Prev: CareVue Interface, Up: CareVue Interface The ADT Application =================== The following is a table of ADT data, that can be effectively transmitted to the CareVue system, other data items are just ignored. FIELDNAME CONTENTS cvHL7 HL7 REMARKS --------------- --------------- --------------- --------------- ----------- name string ZDM, PID PID.PatName Vorname string ZDM, PID PID.PatName acctNum Patient ID ZDM PID.PatIdIntId (1) medRecNum Visit-No. ZDM, PID PV1.VisitNum (1) sex sex-code ZDM PID.Sex DOB date ZDM PID.DateOfBirth admDate date ZDM PV1.AdmitDateTime attendMD dept.-code ZDM PV1.ConSulDoc (2) Bett bed-code PV1 PV1.AssPatLoc Zimmer bed-code PV1 PV1.AssPatLoc Station dept.-code PV1 PV1.AssPatLoc Entlass.grund discharge-code PV1 PV1.DisDis service code ZDM PV1.HosSer (3) Diagnose string ZDM DG1.DiaGnoDes diagnose code ZDM DG1 (3) originalSeverity apache-score ZDM OBX currentSeverity apache-score ZDM OBX allergy1 string ZDM AL1[0].AllCodeMneDes.Text allergy2 string ZDM AL1[1].AllCodeMneDes.Text allergy3 string ZDM AL1[2].AllCodeMneDes.Text nextKin string ZDM NK1.Name (6) kinPhone string ZDM NK1.PhoneNum[0] (6) kinPhonezwei string ZDM NK1.PhoneNum[1] (6) kinPhonedrei string ZDM NK1.PhoneNum[2] (6) Blutgruppe code ZDM OBX ht measure ZDM OBX (5) admitWt measure ZDM OBX (5) age measure ZDM --- (4) BSA measure ZDM OBX (4,5) Adresse string ZDM PID.PatAdd (6) Telephon string ZDM PID.PhoneNumHome (6) Hausarzt string ZDM NK1.Name (6) HArztTel string ZDM NK1.PhoneNum[0] (6) Remarks: (1) Visit-No. and Patient-ID are configured such that they must be exchanged. (2) The "attending medical doctor" is used as a department here, however there is no implication from this usage, since it is a free text field. (3) This field is currently not used. (4) A derived measure that will be calculated by CareVue and therefore need not be transmitted. (5) It is impossible to transmit this value neither via the HL7 ADT interface nor via CLI. (6) The next of kin (also called `associated party' since HL7 version 2.3) must be qualified by the contact role code, which is `user defined' -- meaning undefined yet. The following values will be used: CODE MEANING GERMAN ---- ------------------ ---------------------- EM emergency address Not-Adresse NK next of kin (anderer) Angehöriger FD family doctor Hausarzt The discharge-code uses the following values: `HOME' Home `FACILITY' other facility `DECEASED' deceased `AMA' against medical advice `OTHER' other `NONE' no discharge status (= NULL value?) The ZDM segment is configured as follows: demogPropNames[1] = "name", demogPropNames[2] = "Vorname", demogPropNames[3] = "acctNum", demogPropNames[4] = "medRecNum", demogPropNames[5] = "sex", demogPropNames[6] = "DOB", demogPropNames[7] = "admDate", demogPropNames[8] = "attendMD", demogPropNames[9] = "Diagnose", demogPropNames[10] = "allergy1", demogPropNames[11] = "allergy2", demogPropNames[12] = "allergy3", demogPropNames[13] = "nextKin", demogPropNames[14] = "kinPhone", demogPropNames[15] = "kinPhonezwei", demogPropNames[16] = "kinPhonedrei", demogPropNames[17] = "Hausarzt", demogPropNames[18] = "HArztTel", demogPropNames[19] = "Adresse", demogPropNames[20] = "Telephon", demogPropNames[21] = "originalSeverity", Before a ADT request is forwarded to CareVue, the gateway must check the state of the CareVue census regarding this request in order to make sure that: * the patient is not already admitted * the assigned patient location is not already occupied * the assigned location is occupied *because* the already admitted patient was assigned to the location specified Moreover, a newly admitted patient must have database spaces reserved for admission height, weight and BSA values. These are accepted by the gateway as OBX segments in the ADT messages. There is, however, no other way to register these values into CareVue other than by directly use the IDB. There is a shell script `/usr/hl7/etc/idb_direct' that performs these tasks, see *Note idb_direct::. The apache score can be sent for CareVue's "Original Severity" in an OBX segment. According to HL7 v2.2 chapter 7, its observation identifier will be `1000.17^APACHE SCORE^AS4', unless there is a LOINC code for it. No unit is applicable here.  File: appman.info, Node: CLI, Next: cvgateway, Prev: ADT, Up: CareVue Interface The Result Report Application ============================= The major task of the ORU message gateway is to build a cvHL7 ORU message that contains only those results that are configured for CareVue by means of the `LabEventMap' table. Observation values must be expressed in the right format and unit of measure. CareVue requires the observation value to be sent as a numerically formatted string (ST) value, not more than 7 characters in length. The Observation Ids are freely configureable strings. LOINC codes should be used where possible and therefore the LOINC database should be extended where it seems reasonable (see *Note LOINC::). The gateway needs a list of values configured for CareVue that is supplemented with further information about the nature of the observation values. The name of this list is `LabEventInfo' and its configuration is explained in *Note LabEventInfo::. Since it is so essential that the `LabEventInfo' database always corresponds to CareVue's `LabEventMap' it is recommended that the CareVue table is not edited manually (by means of CareVue's configuration tool) but that it is derived from the `LabEventInfo' table. The "manager" of the latter database, `LabEventInfoMgr', provides an option that generates IDB commands. These can be fed to IDB in order to set up the LabEventMap. See *Note LabEventInfoMgr:: for more.