package de.uniluebeck.mi.projmi6.hapi; import ca.uhn.hl7v2.DefaultHapiContext; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.HapiContext; import ca.uhn.hl7v2.app.Connection; import ca.uhn.hl7v2.llp.LLPException; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v251.datatype.XCN; import ca.uhn.hl7v2.model.v251.message.ACK; import ca.uhn.hl7v2.model.v251.message.ADT_A01; import ca.uhn.hl7v2.model.v251.segment.*; import de.uniluebeck.mi.projmi6.Main; import de.uniluebeck.mi.projmi6.db.DBHandler; import de.uniluebeck.mi.projmi6.model.*; import org.slf4j.LoggerFactory; import java.io.IOException; import java.sql.SQLException; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; import java.util.List; /** * Manages all HL7 sending tasks. This includes: creating a message, sending the message, * Created by taschi on 22.11.15. * */ public class HL7Sender { /** * generates an ADT_A05 message for data exchange with OPS group * * * @param fall to create the message from this content. patient and diagnosis are linked to fall * @throws Exception */ public static void createMessageADT_A01(Fall fall) throws HL7Exception, IOException, SQLException { Patient patient = fall.getPatient(); ADT_A01 adt = new ADT_A01(); //default MSH Values (Sets Segments: 1,2,7,9,10,11 adt.initQuickstart("ADT", "A01", "P"); //MSH Segment: MSH mshSegment = adt.getMSH(); mshSegment.getMsh3_SendingApplication().getNamespaceID().parse("KISGruppe6"); mshSegment.getMsh5_ReceivingApplication().getNamespaceID().parse("OPS Gruppe von Maurice und Torben"); mshSegment.getMsh12_VersionID().getVersionID().parse("2.5.1"); mshSegment.getMsh15_AcceptAcknowledgmentType().parse("AL"); //EVN Segment: EVN evnSegment = adt.getEVN(); evnSegment.getEvn1_EventTypeCode().parse("A01"); evnSegment.getEvn2_RecordedDateTime().getTime().setValue(mshSegment.getDateTimeOfMessage().encode()); evnSegment.getEvn4_EventReasonCode().parse("01"); //PID PID pidSegment = adt.getPID(); pidSegment.getPid2_PatientID().getIDNumber().parse(String.valueOf(patient.getPatID())); pidSegment.getPid3_PatientIdentifierList(0).getIDNumber().parse(Integer.toString(patient.getPatID())); pidSegment.getPid5_PatientName(0).getFamilyName().getSurname().parse(patient.getNachname()); pidSegment.getPid5_PatientName(0).getGivenName().parse(patient.getVorname()); pidSegment.getPid7_DateTimeOfBirth().getTime().setValue(Date.from(patient.getGeburtsdatum().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())); pidSegment.getPid8_AdministrativeSex().parse(String.valueOf(patient.getGeschlecht().id())); pidSegment.getPid11_PatientAddress(0).getStreetAddress().getStreetName().parse(patient.getStrasse()); pidSegment.getPid11_PatientAddress(0).getStreetAddress().getDwellingNumber().parse(patient.getHausnummer()); pidSegment.getPid11_PatientAddress(0).getCity().parse(patient.getOrt()); pidSegment.getPid13_PhoneNumberHome(0).getTelephoneNumber().parse(patient.getTelefon()); pidSegment.getPid16_MaritalStatus().getAlternateIdentifier().parse(patient.getFamilienstand().toString()); //Diagnosen (DG1 Segmente des PV1 Segments List diagnosen = DBHandler.getDiagnosenByFall(fall); PV1 pv1Segment = adt.getPV1(); pv1Segment.getPv12_PatientClass().parse("U"); int i = 1; for (Diagnose diagnose : diagnosen) { Mitarbeiter arzt = diagnose.getArzt(); DG1 dg1 = adt.getDG1(i - 1); dg1.getDg11_SetIDDG1().setValue(String.valueOf(i)); dg1.getDg13_DiagnosisCodeDG1().getIdentifier().parse(diagnose.getIcd10code().getCode()); XCN xcn = dg1.getDg116_DiagnosingClinician(0); xcn.getIDNumber().setValue(arzt.getEinweisenderArzt()); xcn.getGivenName().setValue(arzt.getVorname()); xcn.getFamilyName().getSurname().setValue(arzt.getNachname()); xcn.getPrefixEgDR().setValue(arzt.getTitel()); dg1.getDg14_DiagnosisDescription().parse(diagnose.getFreiText()); dg1.getDg16_DiagnosisType().parse(diagnose.getDiagArt().id()); i++; } sendMessage(adt); } /** * Sending message handler. Calls function to send current message * @param message * @throws HL7Exception */ private static void sendMessage(Message message) throws HL7Exception { if (message instanceof ADT_A01) { sendMessageADT_A01(message); } } /** * sends an ADT_A01 message and waits ca 5 seconds for an ACK. If no ACK occurs it sends the message ONLY 5 times again * if after 5 times no ack occurs log message * write log historie in database * @param message you want to send * @throws HL7Exception */ private static void sendMessageADT_A01(Message message) throws HL7Exception { ADT_A01 adt_a01 = (ADT_A01) message; HapiContext context = new DefaultHapiContext(); Connection connection; try { connection = context.newClient(Main.OPS_IP, Main.OPS_PORT, false); } catch (HL7Exception e) { LoggerFactory.getLogger(HL7Sender.class).error("Konnte aus irgendeinem Grund keine HL7 Nachricht senden. OPS Server down?"); return; } Message response = null; HL7LogEntry messageEntry = new HL7LogEntry(); HL7LogEntry responseEntry = new HL7LogEntry(); messageEntry.setMessage(message.encode()); messageEntry.setSource("127.0.0.1:1234"); // TODO: Kann man den lokal genutzen Port raus finden? messageEntry.setDirection(HL7LogEntry.Direction.OUT); messageEntry.setTimestamp(LocalDateTime.now()); messageEntry.setTimestamp(HL7Utils.parseLocalDateTime(adt_a01.getMSH().getDateTimeOfMessage().getTime())); HL7Utils.logHL7MessageToDatabase(messageEntry); try { int count = 0; // 5 Versuche starten und schauen ob man ein ACK bekommt. while (!(response instanceof ACK) && count < 5) { if (count > 0) { Thread.sleep(5000); } response = connection.getInitiator().sendAndReceive(adt_a01); count++; } } catch (HL7Exception | LLPException | IOException | InterruptedException e) { LoggerFactory.getLogger(HL7Sender.class).warn("Bekomme aus irgendeinem Grund kein ACK."); connection.close(); return; } responseEntry.setMessage(response.encode()); responseEntry.setSource(Main.OPS_IP + ":" + Main.OPS_PORT); responseEntry.setDirection(HL7LogEntry.Direction.IN); responseEntry.setTimestamp(LocalDateTime.now()); HL7Utils.logHL7MessageToDatabase(responseEntry); connection.close(); } }