Jump to content
damos

ICS as HL7 Server

Recommended Posts

Hi i am Testing ICS as HL7 Server on AvailDataAvailable  i have wrote

 

procedure TcpSrvForm.ClientDataAvailable( Sender : TObject;  Error  : Word);
Var
  Client: TWSocketClient;
  Buffer: AnsiString;
  ReceivedData: string;
  AckMsg: string;
  Len: Integer;
begin
  if Error <> 0 then
  begin
    Display('Socket Error: ', Error);
    Exit;
  end;

    Client := Sender as TWSocketClient;


  Len := Client.ReadCount;
  if Len <= 0 then Exit;

  SetLength(Buffer, Len);
  Client.Receive(@Buffer[1], Len);

  // Convert buffer to string and trim unnecessary spaces
  ReceivedData := Trim(String(Buffer));

  // Ensure message ends with <CR>
 
 if (not ReceivedData.IsEmpty)  and (Strutils.RightStr(ReceivedData,1)=#13)

then
  begin
    Display('Received HL7 Message: '+ReceivedData);

    // Create HL7 Acknowledgment (ACK)
    AckMsg := 'MSH|^~\&|RECEIVER|SENDER|ACK||' + FormatDateTime('YYYYMMDDHHNNSS', Now) +
              '||ACK|' + IntToStr(Random(1000000)) + '|P|2.3' + #13 +
              'MSA|AA|' + 'MSG12345' + #13;

    // Send ACK back to client
    Client.SendStr(#11+AckMsg+#28+#13);
     Display('Sent ACK: '+AckMsg);

  end
  else
  begin

    Display('Incomplete HL7 message received (waiting for <CR>)');
  end;
  end;

Each HL7 block has the following format

 

#11+HL7Block+#28+#13  or VT +HL7Message +FS+CR

Each HL7Block consist 

Messages  ending with CR

Example

VT

MSH|^~\&|OR-CO|MIRTH|LISSYSTEM||20191126132820||ADT^A04^ADT_A04|2653973|P|2.4+CR
EVN|A01||||OR-CO|20191126132400+CR
PID|||22522527||CCCCCCCCCC^VVVVVVVV^KKKKKKKK||19581003000000|M|||ΠΕΤΡΟΥ ΡΑΛΛΗ 3^^ΑΘΗΝΑ^^15121||2106127519||||||27014802733+CR
NK1|1|^ΜΑΡΙΑ|MTH+CR
PV1||E|392^102106001^0^392||||1068^SSSSSS^DDDDDD||||||||||||1-2611222|||||||||||||||||||||||||20191126132400+CR
DG1|||D64.9^LLLLLLLLLLLL+CR
IN1|||551OOOOOOOOOOOOOOO|||||||||||||||||||||||||||||||||||||||||||||11456652+CR

VT+CR

 

 

 

 This is Working only When Client is disconnected  never reach data from client

 Each message Block from Client has to be Acknowledgement by HL7 ACK message

 I have tested with LineEnd=#13 and LineEnd=#28#13

Share this post


Link to post

Never heard of HL7, but it looks like a simple ASCII protocol, one line at a time. 

 

I'd suggest you use the TIcsIpStrmLog component in TCP Server mode which has an onRecvEvent that returns a simple line at a time, you can define the line end in various ways. 

 

The main sample is  OverbyteIcsIpStmLogTst,dpr that sends and receives lines of data, including to itself.  ICS V9,4 adds a new component OverbyteIcsAppMonSrv.pas that handles a text protocol very similar to your example with | as field separators, communicating between different ICS applications, with a new sample IcsAppMon.dpr use the server component to collect information from multiple clients and return information those clients. 

 

Angus

 

Share this post


Link to post

I use a TWSocket to listen for HL7 transmissions. It works perfectly.

 

Ken

Share this post


Link to post

I have used TWSocket for hospital application (HL7 V2.3) and never had any issue.

You should turn line mode on and use CR as line end.

The as it is ASCII, use ReceiveStr to get the lines one at a time into a string.

Share this post


Link to post

I follow the example and Use

 

procedure TForm6.WSocketServer1DataAvailable(Sender: TObject; ErrCode: Word);

Var
  ReceivedData: string;
  AckMsg: string;

begin


  if ErrCode <> 0 then Exit;

   with Sender as TWSocket do begin
     ReceivedData := ReceiveStr;
     ReceivedData := LeftStr(ReceivedData,Length(ReceivedData)-Length(LineEnd));  // remove EndOfLine
     DisplayMemo.Lines.Add('Line: '+ IntToStr(Length(ReceivedData)) +' '+ReceivedData);
   end;


     AckMsg := 'MSH|^~\&|RECEIVER|SENDER|ACK||' + FormatDateTime('YYYYMMDDHHNNSS', Now) +
              '||ACK|' + IntToStr(Random(1000000)) + '|P|2.3' + #13 +
              'MSA|AA|' + 'MSG12345' + #13;


end;

 

Status.png.defe0bce5c860afdbcb34fb50a75be0f.png

Never get the message from Client can you give a simple example that line ends with FS+CR  (#28#13)  With Indy works Fine

Share this post


Link to post

Of course TWSocket can be used for HL7, but using TIcsIpStrmLog requires a lot less code.  OverbyteIcsAppMonSrv.pas even parses the | delimited fields.  

 

Angus

 

Share this post


Link to post
1 hour ago, damos said:

Never get the message from Client can you give a simple example that line ends with FS+CR  (#28#13)

In HL7, end of segment is single CR (#13). Set TWSocket LineEnd to single #13.

Share this post


Link to post

I have to disagree with you General format on common versions of HL7  2.3....2.7 are standard   VT+HL7Block+FS+CR  , each  HL7Block consist of HL7 records according the version each line end with CR

\x0B

MSH|^~\&|... 

PID|... PV1|... 

\x1C\x0D

i have to read all the block that is ending with FS+CR (MIRTH OPERATION) and answer with ACk or NAK the HL7 message that is the flow Control

 

I have also try with LineEnd=#13

i have attach simple project and simple Flow from HL7 client

Response.thumb.png.de2df74fb82715bf841365d862640c10.png

 

Socket.rar

Share this post


Link to post

You would be better to avoid using LineMode if the lines are 'unusual', always read all received data, buffer it, and check for end of line/row/packet yourself, which can be multiple methods. 

 

That is what the TIcsIpStrmLog  component does, but you may need to copy the code to add more flexibility.

 

Angus

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×