Beispiel #1
0
 def ack(self, resp_type='AA'):
     """
     Build ACK response for incoming message.
     :type resp_type: str
     :param resp_type: 'AA' for ACK, 'AR' for Reject, 'AE' for Application Error
     :rtype: HL7apy.core.Message
     :return: ACK ('AA') or NAK ('AE', 'AR') message
     """
     resp_types = ('AA', 'AR', 'AE')
     if resp_type not in resp_types:
         raise ValueError(
             "Invalid ACK type. Expected one of: {}".format(resp_types))
     resp = Message('ACK', version='2.5.1')
     resp.msh.msh_3 = 'LIS'
     resp.msh.msh_4 = 'LIS Facility'
     resp.msh.msh_5 = self.msg.msh.msh_3
     resp.msh.msh_6 = Config.LABNAME
     resp.msh.msh_9 = 'ACK^R22^ACK'
     resp.msh.msh_10 = self.run_info.msg_guid
     resp.msh.msh_11 = 'P'
     resp.msh.msh_12 = '2.5.1'
     resp.msh.msh_18 = 'UNICODE UTF-8'
     resp.msh.msh_21 = 'LAB-29^IHE'
     resp.add_segment('MSA')
     resp.msa.msa_1 = resp_type
     resp.msa.msa_2 = self.run_info.msg_guid
     if resp_type != 'AA':
         pass
     end_resp = add_mllp_frame(resp.to_er7())
     assert isinstance(end_resp, bytes)
     return end_resp
Beispiel #2
0
    def _create_message(self, results, ack_code):
        """
        Creates the final RSP_K21 response message. If no errors occurred and some results have been found, the message
        will carry as many different PID segments as the number of the results.

        :type:  results  ``list``
        :param: results a list providing the Gnuhealth ORM query results

        :type:  ack_code  ``str``
        :param: ack_code it is the ack:code to be put in the MSA segment. If no errors occurred, the code wull be of
            positive ACK (AA); else, one of the negative acks (AE, AR)

        :return: an hl7apy ``Message`` class instance, which is the final RSP_K21 message
        """
        try:
            qry_ack_code = 'OK'
            if len(results) == 0:
                qry_ack_code = 'NF'
            
            is_pdqv = self.is_pdqv_message()
            logger.debug("Creating response message...")
            if is_pdqv:
                message_profile = load_message_profile(os.path.join(_get_message_profiles_dir(), "pdqv_response"))
                message_structure = PDQV_MESSAGE_STRUCTURE
            else:
                message_profile = load_message_profile(os.path.join(_get_message_profiles_dir(), "pdq_response"))
                message_structure = PDQ_MESSAGE_STRUCTURE
                
            message = Message(message_structure, version='2.5', validation_level=VALIDATION_LEVEL.STRICT,
                              reference=message_profile)
            
            self._set_msh(message, is_pdqv)
            
            msa = message.add_segment("MSA")
            msa.msa_1 = ack_code
            msa.msa_2 = self.msg.msh.msh_10.msh_10_1

            qak = message.add_segment("QAK")
            qak.qak_1 = self.msg.qpd.qpd_2
            qak.qak_2 = qry_ack_code
            qak.qak_4.qak_4_1 = str(len(results))  # total results
            qak.qak_5.qak_5_1 = str(len(results))  # sent results
            qak.qak_6.qak_6_1 = "0"  # remaining results
            
            message.add_segment("QPD")
            message.qpd = self.msg.qpd

            message = self._create_pdq_res_list(message, message_structure, results)
            return message
        except Exception, e:
            logger.error('Error during Message Creation, %s' % e)
                 corId = m.msh.children.get("MSH_10").value
                 answer.msa.children.get("MSA_2").value = corId
             else:
                 # answer with pcd-05 message
                 print("************ Got Alarm {} ************".format(
                     alarmTypeTxt))
                 print("Full message {}: \n{}".format(
                     datetime.now(), pretty(m)))
                 counter = m.children.get("OBR").children.get(
                     "OBR_3").children[0].value
                 alarmId = m.children.get("OBR").children.get(
                     "OBR_3").children[1].value
                 answer.msh.children.get(
                     "MSH_9").value = "ORA^R41^ORA_R41"
                 answer.msh.children.get("MSH_4").value = "MockAM"
                 answer.add_segment("OBR").children.get(
                     "OBR_3").value = "{}^{}".format(counter, alarmId)
                 answer.add_segment("PRT").children.get(
                     "PRT_3").value = "Delivered"
                 answer.msh.children.get(
                     "MSH_10").value = m.msh.children.get(
                         "MSH_10").value
             print("Answering {}: \n{}".format(datetime.now(),
                                               pretty(answer)))
             inSock.sendall(answer.to_mllp().encode('UTF-8'))
             print("*******************************")
         else:
             print("Got unknown message type: {}".format(msgType))
     except:
         traceback.print_exc()
 except HL7apyException as e:
     traceback.print_exc()
class PCD04Message:
    HeartbeatAlarmType = "196614^MDC_EVT_ACTIVE^MDC"

    def getMessage(self):
        return self._ORU_R40

    def __init__(self):
        self._myMsgControlIdIter = 0
        self._ORU_R40 = Message(version="2.6")

    def createPCD04Message(self,
                           AssignedPatientLocation,
                           EquipII,
                           PatientIdList,
                           PatientName,
                           PatientDoB,
                           PatientSex,
                           AlertType,
                           AlertText,
                           AlertPhase,
                           AlertKindPrioStr,
                           SrcContainmentTreeId,
                           ObsType,
                           ObsValue,
                           ObsValueType,
                           ObsUnit,
                           UniqueAlertUuid,
                           AlertKind,
                           ObsDetTime=None,
                           AlertCounter=0,
                           AlertState="active",
                           AlertInactivationState="enabled",
                           SendingFacility="IHE_AR",
                           ReceivingApplication=None,
                           ProcessingId="D",
                           MdsType="",
                           VmdType=""):
        messageTime = datetime.now().astimezone()
        messageTimeStr = messageTime.strftime("%Y%m%d%H%M%S%z")

        self.createMshSegmentAcm(messageTimeStr, SendingFacility,
                                 ReceivingApplication, ProcessingId)
        self.createPidSegmentAcm(PatientIdList, PatientName, PatientDoB,
                                 PatientSex)
        self.createPv1SegmentAcm(AssignedPatientLocation)

        self._EquipII = EquipII
        self.createObrSegmentAcm(messageTimeStr, UniqueAlertUuid, AlertCounter)
        self._obxCount = 0
        MdsTree = "{}.0.0".format(SrcContainmentTreeId.split(".")[0])
        VmdTree = "{}.{}.0".format(
            SrcContainmentTreeId.split(".")[0],
            SrcContainmentTreeId.split(".")[1])
        #AlertTree = SrcContainmentTreeId.split('.')[2]

        self.createObxSegmentAcm(0, MdsType, ObsValueType="", CTP=MdsTree)
        self.createObxSegmentAcm(0, VmdType, ObsValueType="", CTP=VmdTree)
        self.createObxSegmentAcm(1,
                                 AlertType,
                                 AlertText,
                                 CTP=SrcContainmentTreeId)
        self.createObxSegmentAcm(2,
                                 ObsType,
                                 ObsValue,
                                 ObsValueType=ObsValueType,
                                 ObsUnit=ObsUnit,
                                 ObsTimeStr=ObsDetTime,
                                 CTP=SrcContainmentTreeId)
        self.createObxSegmentAcm(3,
                                 "68481^MDC_ATTR_EVENT_PHASE^MDC",
                                 AlertPhase,
                                 CTP=SrcContainmentTreeId)
        self.createObxSegmentAcm(4,
                                 "68482^MDC_ATTR_ALARM_STATE^MDC",
                                 AlertState,
                                 CTP=SrcContainmentTreeId)
        self.createObxSegmentAcm(5,
                                 "68483^MDC_ATTR_ALARM_INACTIVATION_STATE^MDC",
                                 AlertInactivationState,
                                 CTP=SrcContainmentTreeId)
        self.createObxSegmentAcm(6,
                                 "68484^MDC_ATTR_ALARM_PRIORITY^MDC",
                                 AlertKindPrioStr,
                                 CTP=SrcContainmentTreeId)
        self.createObxSegmentAcm(7,
                                 "68485^MDC_ATTR_ALERT_TYPE^MDC",
                                 AlertKind,
                                 CTP=SrcContainmentTreeId)

    def addWatchdogObxSegment(self,
                              timeoutPeriod,
                              timeoutUnit="264320^MDC_DIM_SEC^MDC",
                              MdsTree="1.0.0"):
        self.createObxSegmentAcm(8,
                                 "67860^MDC_ATTR_CONFIRM_TIMEOUT^MDC",
                                 ObsValue=timeoutPeriod,
                                 ObsUnit=timeoutUnit,
                                 ObsValueType="NM",
                                 CTP=MdsTree)

    def createMshSegmentAcm(self, messageTimeStr, SendingFacility,
                            ReceivingApplication, ProcessingId):
        MsgControlIdVal = str(self._myMsgControlIdIter)
        self._myMsgControlIdIter += 1

        self._ORU_R40.msh.children.get(
            "MSH_3").value = ActorEui64  # Sending Application
        self._ORU_R40.msh.children.get(
            "MSH_4").value = SendingFacility  # Sending Facility
        if (ReceivingApplication is not None):
            self._ORU_R40.msh.children.get(
                "MSH_5").value = ReceivingApplication  # Receiving Application
        self._ORU_R40.msh.children.get(
            "MSH_7").value = messageTimeStr  # Date/Time Of Message
        self._ORU_R40.msh.children.get(
            "MSH_9").value = "ORU^R40^ORU_R40"  # Message Type
        self._ORU_R40.msh.children.get(
            "MSH_10").value = MsgControlIdVal  # Message Control ID
        self._ORU_R40.msh.children.get(
            "MSH_11").value = ProcessingId  # Processing ID
        self._ORU_R40.msh.children.get(
            "MSH_15").value = AcceptAckTypeAcm  # Accept Acknowledgment Type
        self._ORU_R40.msh.children.get(
            "MSH_16"
        ).value = ApplicationAckType  # Application Acknowledgment Type
        self._ORU_R40.msh.children.get(
            "MSH_21"
        ).value = "IHE_PCD_ACM_001^IHE PCD^1.3.6.1.4.1.19376.1.6.1.4.1^ISO"  # IHE_PCD_ACM_001^IHE PCD^1.3.6.1.4.1.19376.1.6.4.4^ISO

    def createPidSegmentAcm(self, PatientIdList, PatientName, PatientDoB,
                            PatientSex):
        pid = self._ORU_R40.add_segment("PID")
        pid.children.get(
            "PID_3").value = PatientIdList  # Patient Identifier List
        pid.children.get("PID_5").value = PatientName  # Patient Name
        pid.children.get("PID_7").value = PatientDoB
        pid.children.get("PID_8").value = PatientSex

    def createPv1SegmentAcm(self, AssignedPatientLocation):
        # PV1|||CU1^^9042^HOSP1
        pv1 = self._ORU_R40.add_segment("PV1")
        pv1.children.get("PV1_2").value = "I"
        pv1.children.get(
            "PV1_3"
        ).value = AssignedPatientLocation  # Assigned Patient Location

    def incAlertCounter(self):
        obr = self._ORU_R40.children.get("OBR")
        oldCountStr = obr.children.get("OBR_3").value.split('^')
        oldCount = int(oldCountStr[0])
        FillerOrderNumber = str(
            oldCount + 1) + "^" + oldCountStr[1] + "^" + oldCountStr[2]
        obr.children.get(
            "OBR_3").value = FillerOrderNumber  # Filler Order Number
        self._ORU_R40.children.get("OBX")[2].children.get(
            "OBX_5").value = "continue"

    def setControlId(self, id):
        self._ORU_R40.msh.children.get("MSH_10").value = id

    def setAlarmTypeAndText(self, alarmType, alarmText):
        seg1 = self._getObxSegment(1)
        seg1.children.get("OBX_3").value = alarmType
        seg1.children.get("OBX_5").value = alarmText

    def setAlarmValue(self, value, obsType, unit, time):
        seg2 = self._getObxSegment(2)
        seg2.children.get("OBX_6").value = unit
        seg2.children.get("OBX_2").value = obsType
        seg2.children.get("OBX_5").value = str(value)
        seg2.children.get("OBX_14").value = time

    def setAlarmCTP(self, CTP):
        self._CTP = CTP

    def setAlarmId(self, alarmId):
        obr = self._ORU_R40.children.get("OBR")
        obr.children.get("OBR_1").value = "1"
        old = obr.children.get("OBR_3").value.split('^')  # Set ID - OBR
        FillerOrderNumber = str(old[0]) + "^" + alarmId + "^" + old[2]
        parentAlert = "^0&" + alarmId + "&" + old[2]
        obr.children.get(
            "OBR_3").value = FillerOrderNumber  # Filler Order Number

    def setAlarmPhase(self, AlertPhase):
        seg = self._getObxSegment(3)
        seg.children.get("OBX_5").value = AlertPhase

    def setAlarmState(self, AlertState):
        seg = self._getObxSegment(4)
        seg.children.get("OBX_5").value = AlertState

    def setAlarmInactivationState(self, AlertState):
        seg = self._getObxSegment(5)
        seg.children.get("OBX_5").value = AlertState

    def setAlarmPrio(self, AlertPrio):
        seg = self._getObxSegment(6)
        seg.children.get("OBX_5").value = AlertPrio

    def setAlarmKind(self, AlertKind):
        seg = self._getObxSegment(7)
        seg.children.get("OBX_5").value = AlertKind

    def getDeviceId(self):
        return self._ORU_R40.children.get("OBX").children.get("OBX_18").value

    def getLocation(self):
        pv1 = self._ORU_R40.children.get("PV1")
        return pv1.children.get("PV1_3").value

    def getEquip(self):
        seg = self._ORU_R40.children.get("OBX")
        return seg.children.get("OBX_18").value

    def getPatientId(self):
        pid = self._ORU_R40.children.get("PID")
        return pid.children.get("PID_3").value

    def getPatientName(self):
        pid = self._ORU_R40.children.get("PID")
        return pid.children.get("PID_5").value

    def getPatientDoB(self):
        pid = self._ORU_R40.children.get("PID")
        return pid.children.get("PID_7").value

    def getPatientSex(self):
        pid = self._ORU_R40.children.get("PID")
        return pid.children.get("PID_8").value

    def _getObxSegment(self, nr):
        # iterate over obx segments
        obx = self._ORU_R40.children.get("OBX")
        retVal = None
        for oneObx in obx:
            if oneObx.children.get("OBX_1").value == str(nr):
                retVal = oneObx
        return retVal

    def createObrSegmentAcm(self, messageTimeStr, UniqueAlertUuid,
                            AlertUpdate):
        obr = self._ORU_R40.add_segment("OBR")
        obr.children.get("OBR_1").value = "1"  # Set ID - OBR
        FillerOrderNumber = str(
            AlertUpdate) + "^" + UniqueAlertUuid + "^" + ActorEui64
        parentAlert = "^0&" + UniqueAlertUuid + "&" + ActorEui64Sub
        obr.children.get(
            "OBR_3").value = FillerOrderNumber  # Filler Order Number
        obr.children.get(
            "OBR_4"
        ).value = "196616^MDC_EVT_ALARM^MDC"  # Universal Service Identifier
        obr.children.get(
            "OBR_7").value = messageTimeStr  # Observation Date/Time
        #    if (AlertUpdate > 0):
        obr.children.get("OBR_29").value = parentAlert  # Parent

    def createObxSegmentAcm(self,
                            Set_ID,
                            ObsId,
                            ObsValue=None,
                            ObsUnit=None,
                            ObsTimeStr=None,
                            ObsSite=None,
                            ObsValueType="ST",
                            CTP="x.x.x"):
        obx = self._ORU_R40.add_segment("OBX")
        self._obxCount += 1
        obx.children.get("OBX_1").value = str(self._obxCount)  # Set ID
        if ObsValueType != "":
            obx.children.get("OBX_2").value = ObsValueType
            obx.children.get("OBX_11").value = "F"  # Observation Result Status
        else:
            obx.children.get("OBX_11").value = "X"

        obx.children.get("OBX_3").value = ObsId  # Observation Identifier
        obx.children.get("OBX_4").value = CTP + "." + str(
            Set_ID)  # Observation Sub-ID
        if ObsValue:
            obx.children.get("OBX_5").value = str(
                ObsValue)  # Observation Value

        if ObsUnit is not None:
            obx.children.get("OBX_6").value = ObsUnit  # Units

        if (ObsTimeStr is not None):
            obx.children.get(
                "OBX_14").value = ObsTimeStr  # Date/Time of the Observation

        obx.children.get(
            "OBX_18").value = self._EquipII  # Equipment Instance Identifier

        if (ObsSite is not None):
            obx.children.get("OBX_20").value = ObsSite  # Observation Site